mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
add datetimepicker
This commit is contained in:
parent
2dc3941654
commit
c3f9ced46e
@ -34,5 +34,6 @@
|
|||||||
"toast": "./packages/toast/index.js",
|
"toast": "./packages/toast/index.js",
|
||||||
"uploader": "./packages/uploader/index.js",
|
"uploader": "./packages/uploader/index.js",
|
||||||
"swipe": "./packages/swipe/index.js",
|
"swipe": "./packages/swipe/index.js",
|
||||||
"swipe-item": "./packages/swipe-item/index.js"
|
"swipe-item": "./packages/swipe-item/index.js",
|
||||||
|
"datetime-picker": "./packages/datetime-picker/index.js"
|
||||||
}
|
}
|
||||||
|
94
docs/examples-docs/datetime-picker.md
Normal file
94
docs/examples-docs/datetime-picker.md
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
minHour: 10,
|
||||||
|
maxHour: 20,
|
||||||
|
minDate: new Date()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handlePickerChange(picker, values) {
|
||||||
|
// picker.setColumnValues(1, citys[values[0]]);
|
||||||
|
console.log(values);
|
||||||
|
},
|
||||||
|
handlePickerCancel() {
|
||||||
|
alert('picker cancel');
|
||||||
|
},
|
||||||
|
handlePickerConfirm() {
|
||||||
|
alert('picker confirm');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
## Picker组件
|
||||||
|
|
||||||
|
模仿iOS中的`UIPickerView`。
|
||||||
|
|
||||||
|
### 基础用法
|
||||||
|
|
||||||
|
:::demo 基础用法
|
||||||
|
```html
|
||||||
|
<zan-datetime-picker
|
||||||
|
type="time"
|
||||||
|
:min-hour="minHour"
|
||||||
|
:max-hour="maxHour"
|
||||||
|
:min-date="minDate"
|
||||||
|
@change="handlePickerChange">
|
||||||
|
</zan-datetime-picker>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
minHour: 10,
|
||||||
|
maxHour: 20,
|
||||||
|
minDate: new Date()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handlePickerChange(picker, values) {
|
||||||
|
picker.setColumnValues(1, citys[values[0]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| visibileColumnCount | 每一列可见备选元素的个数 | Number | 5 | |
|
||||||
|
| itemHeight | 选中元素区高度 | Number | 44 | |
|
||||||
|
| columns | 对象数组,配置每一列显示的数据 | Array | | |
|
||||||
|
| showToolbar | 是否在组件顶部显示一个toolbar | Boolean | true | |
|
||||||
|
|
||||||
|
### columns
|
||||||
|
|
||||||
|
`API`中的`columns`为一个对象数组,数组中的每一个对象配置每一列,每一列有以下`key`:
|
||||||
|
|
||||||
|
| key | 说明 |
|
||||||
|
|-----------|-----------|
|
||||||
|
| values | 列中对应的备选值 |
|
||||||
|
| defaultIndex | 初始选中值的索引,默认为0 |
|
||||||
|
| className | 为对应列添加特殊的`class` |
|
||||||
|
|
||||||
|
### change事件
|
||||||
|
|
||||||
|
在`change`事件中,可以获取到`picker`实例,对`picker`进行相应的更新等操作:
|
||||||
|
|
||||||
|
| 函数 | 说明 |
|
||||||
|
|-----------|-----------|
|
||||||
|
| getColumnValue(index) | 获取对应列中选中的值 |
|
||||||
|
| setColumnValue(index, value) | 设置对应列中选中的值 |
|
||||||
|
| getColumnValues(index) | 获取对应列中所有的备选值 |
|
||||||
|
| setColumnValues(index, values) | 设置对应列中所有的备选值 |
|
||||||
|
| getValues() | 获取所有列中被选中的值,返回一个数组 |
|
||||||
|
| setValues(values) | `values`为一个数组,设置所有列中被选中的值 |
|
8
packages/datetime-picker/CHANGELOG.md
Normal file
8
packages/datetime-picker/CHANGELOG.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
## 0.0.2 (2017-01-20)
|
||||||
|
|
||||||
|
* 改了bug A
|
||||||
|
* 加了功能B
|
||||||
|
|
||||||
|
## 0.0.1 (2017-01-10)
|
||||||
|
|
||||||
|
* 第一版
|
26
packages/datetime-picker/README.md
Normal file
26
packages/datetime-picker/README.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# @youzan/<%= name %>
|
||||||
|
|
||||||
|
!!! 请在此处填写你的文档最简单描述 !!!
|
||||||
|
|
||||||
|
[![version][version-image]][download-url]
|
||||||
|
[![download][download-image]][download-url]
|
||||||
|
|
||||||
|
[version-image]: http://npm.qima-inc.com/badge/v/@youzan/<%= name %>.svg?style=flat-square
|
||||||
|
[download-image]: http://npm.qima-inc.com/badge/d/@youzan/<%= name %>.svg?style=flat-square
|
||||||
|
[download-url]: http://npm.qima-inc.com/package/@youzan/<%= name %>
|
||||||
|
|
||||||
|
## Demo
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||||
|
|-----------|-----------|-----------|-------------|-------------|
|
||||||
|
| className | 自定义额外类名 | string | '' | '' |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
[MIT](https://opensource.org/licenses/MIT)
|
3
packages/datetime-picker/index.js
Normal file
3
packages/datetime-picker/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import DateTimePicker from './src/datetime-picker';
|
||||||
|
|
||||||
|
export default DateTimePicker;
|
10
packages/datetime-picker/package.json
Normal file
10
packages/datetime-picker/package.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "@youzan/zan-datetime-picker",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "datetime picker component",
|
||||||
|
"main": "./index.js",
|
||||||
|
"author": "niunai <niunai@youzan.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {},
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
216
packages/datetime-picker/src/datetime-picker.vue
Normal file
216
packages/datetime-picker/src/datetime-picker.vue
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
<template>
|
||||||
|
<zan-picker
|
||||||
|
:columns="columns"
|
||||||
|
:visible-item-count="visibleItemCount"
|
||||||
|
@change="handlePickerChange"
|
||||||
|
@confirm="handlePickerConfirm"
|
||||||
|
showToolbar>
|
||||||
|
</zan-picker>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Picker from 'packages/picker';
|
||||||
|
|
||||||
|
const allowedType = ['time', 'date', 'datetime'];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'zan-datetime-picker',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Picker
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'datetime',
|
||||||
|
validator(value) {
|
||||||
|
return allowedType.indexOf(value) > -1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
visibleItemCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
minDate: {
|
||||||
|
type: Date,
|
||||||
|
default() {
|
||||||
|
return new Date(new Date().getFullYear() - 10, 0, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
maxDate: {
|
||||||
|
type: Date,
|
||||||
|
default() {
|
||||||
|
return new Date(new Date().getFullYear() + 10, 11, 31);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
minHour: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
maxHour: {
|
||||||
|
type: Number,
|
||||||
|
default: 23
|
||||||
|
},
|
||||||
|
value: null
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
value(val) {
|
||||||
|
this.innerValue = val;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
ranges() {
|
||||||
|
if (this.type === 'time') {
|
||||||
|
return [
|
||||||
|
[this.minHour, this.maxHour],
|
||||||
|
[0, 59]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
debugger
|
||||||
|
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', this.innerValue);
|
||||||
|
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', this.innerValue);
|
||||||
|
|
||||||
|
const result = [
|
||||||
|
[minYear, maxYear],
|
||||||
|
[minMonth, maxMonth],
|
||||||
|
[minDate, maxDate],
|
||||||
|
[minHour, maxHour],
|
||||||
|
[minMinute, maxMinute]
|
||||||
|
];
|
||||||
|
|
||||||
|
if (this.type === 'date') result.splice(3, 2);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
columns() {
|
||||||
|
return this.ranges.map(range => {
|
||||||
|
const values = this.times(range[1] - range[0] + 1, index => {
|
||||||
|
const value = range[0] + index;
|
||||||
|
return value < 10 ? `0${value}` : `${value}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
values
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
times(n, iteratee) {
|
||||||
|
let index = -1;
|
||||||
|
const result = Array(n);
|
||||||
|
|
||||||
|
while (++index < n) {
|
||||||
|
result[index] = iteratee(index);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
getBoundary(type, value) {
|
||||||
|
const boundary = this[`${type}Date`];
|
||||||
|
const year = boundary.getFullYear();
|
||||||
|
let month = 1;
|
||||||
|
let date = 1;
|
||||||
|
let hour = 0;
|
||||||
|
let minute = 0;
|
||||||
|
|
||||||
|
if (type === 'max') {
|
||||||
|
month = 12;
|
||||||
|
date = this.getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
|
||||||
|
hour = 23;
|
||||||
|
minute = 59;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.getFullYear() === year) {
|
||||||
|
month = boundary.getMonth() + 1;
|
||||||
|
if (value.getMonth() + 1 === month) {
|
||||||
|
date = value.getDate();
|
||||||
|
if (value.getDate() === date) {
|
||||||
|
hour = value.getHours();
|
||||||
|
if (value.getHours() === hour) {
|
||||||
|
minute = value.getMinutes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
[`${type}Year`]: year,
|
||||||
|
[`${type}Month`]: month,
|
||||||
|
[`${type}Date`]: date,
|
||||||
|
[`${type}Hour`]: hour,
|
||||||
|
[`${type}Minute`]: minute
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getTrueValue(formattedValue) {
|
||||||
|
if (!formattedValue) return;
|
||||||
|
while (isNaN(parseInt(formattedValue, 10))) {
|
||||||
|
formattedValue = formattedValue.slice(1);
|
||||||
|
}
|
||||||
|
return parseInt(formattedValue, 10);
|
||||||
|
},
|
||||||
|
getMonthEndDay(year, month) {
|
||||||
|
if (this.isShortMonth(month)) {
|
||||||
|
return 30;
|
||||||
|
} else if (month === 2) {
|
||||||
|
return this.isLeapYear(year) ? 29 : 28;
|
||||||
|
} else {
|
||||||
|
return 31;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isLeapYear(year) {
|
||||||
|
return (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0);
|
||||||
|
},
|
||||||
|
isShortMonth(month) {
|
||||||
|
return [4, 6, 9, 11].indexOf(month) > -1;
|
||||||
|
},
|
||||||
|
handlePickerConfirm(values) {
|
||||||
|
this.$emit('confirm', this.innerValue);
|
||||||
|
},
|
||||||
|
handlePickerChange(picker, values, index) {
|
||||||
|
let value;
|
||||||
|
|
||||||
|
if (this.type === 'time') {
|
||||||
|
value = values.join(':');
|
||||||
|
} else {
|
||||||
|
const year = this.getTrueValue(values[0]);
|
||||||
|
const month = this.getTrueValue(values[1]);
|
||||||
|
const maxDate = this.getMonthEndDay(year, month);
|
||||||
|
let date = this.getTrueValue(values[2]);
|
||||||
|
date = date > maxDate ? maxDate : date;
|
||||||
|
let hour = 0;
|
||||||
|
let minute = 0;
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
hour = this.getTrueValue(values[3]);
|
||||||
|
minute = this.getTrueValue(values[4]);
|
||||||
|
}
|
||||||
|
value = new Date(year, month - 1, date, hour, minute);
|
||||||
|
}
|
||||||
|
debugger
|
||||||
|
this.innerValue = value;
|
||||||
|
console.log(value);
|
||||||
|
this.$emit('input', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.innerValue = this.value;
|
||||||
|
if (!this.innerValue) {
|
||||||
|
if (this.type.indexOf('date') > -1) {
|
||||||
|
this.innerValue = this.minDate;
|
||||||
|
} else {
|
||||||
|
const minHour = this.minHour;
|
||||||
|
this.innerValue = `${minHour > 10 ? minHour : '0' + minHour}:00`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -48,6 +48,18 @@
|
|||||||
width: 33.333%;
|
width: 33.333%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@m 4 {
|
||||||
|
.zan-picker-column {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@m 5 {
|
||||||
|
.zan-picker-column {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import Toast from '../packages/toast/index.js';
|
|||||||
import Uploader from '../packages/uploader/index.js';
|
import Uploader from '../packages/uploader/index.js';
|
||||||
import Swipe from '../packages/swipe/index.js';
|
import Swipe from '../packages/swipe/index.js';
|
||||||
import SwipeItem from '../packages/swipe-item/index.js';
|
import SwipeItem from '../packages/swipe-item/index.js';
|
||||||
|
import DatetimePicker from '../packages/datetime-picker/index.js';
|
||||||
|
|
||||||
const install = function(Vue) {
|
const install = function(Vue) {
|
||||||
if (install.installed) return;
|
if (install.installed) return;
|
||||||
@ -69,6 +70,7 @@ const install = function(Vue) {
|
|||||||
Vue.component(Uploader.name, Uploader);
|
Vue.component(Uploader.name, Uploader);
|
||||||
Vue.component(Swipe.name, Swipe);
|
Vue.component(Swipe.name, Swipe);
|
||||||
Vue.component(SwipeItem.name, SwipeItem);
|
Vue.component(SwipeItem.name, SwipeItem);
|
||||||
|
Vue.component(DatetimePicker.name, DatetimePicker);
|
||||||
};
|
};
|
||||||
|
|
||||||
// auto install
|
// auto install
|
||||||
@ -114,5 +116,6 @@ module.exports = {
|
|||||||
Toast,
|
Toast,
|
||||||
Uploader,
|
Uploader,
|
||||||
Swipe,
|
Swipe,
|
||||||
SwipeItem
|
SwipeItem,
|
||||||
|
DatetimePicker
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user