mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-04-06 03:58:05 +08:00
[improvement] DatetimePicker: 使用picker重构
This commit is contained in:
parent
a96083f9ec
commit
8667235b15
@ -1,4 +1,5 @@
|
||||
import Page from '../../common/page';
|
||||
import Toast from '../../dist/toast/toast';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@ -6,14 +7,33 @@ Page({
|
||||
maxHour: 20,
|
||||
minDate: new Date(2018, 0, 1).getTime(),
|
||||
maxDate: new Date(2019, 10, 1).getTime(),
|
||||
currentDate1: new Date(2018, 2, 1).getTime(),
|
||||
currentDate1: new Date(2018, 2, 31).getTime(),
|
||||
currentDate2: null,
|
||||
currentDate3: new Date(2018, 0, 1),
|
||||
currentDate4: '12:00',
|
||||
loading: false
|
||||
},
|
||||
|
||||
onChange(event) {
|
||||
console.log(event);
|
||||
onInput(event) {
|
||||
const { detail, currentTarget } = event;
|
||||
const result = this.getResult(detail, currentTarget.dataset.type);
|
||||
|
||||
Toast(result);
|
||||
},
|
||||
|
||||
getResult(time, type) {
|
||||
const date = new Date(time);
|
||||
switch (type) {
|
||||
case 'datetime':
|
||||
return date.toLocaleString();
|
||||
case 'date':
|
||||
return date.toLocaleDateString();
|
||||
case 'year-month':
|
||||
return `${date.getFullYear()}/${date.getMonth() + 1}`;
|
||||
case 'time':
|
||||
return time;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,37 +1,43 @@
|
||||
<demo-block title="选择完整时间">
|
||||
<van-datetime-picker
|
||||
type="datetime"
|
||||
data-type="datetime"
|
||||
loading="{{ loading }}"
|
||||
value="{{ currentDate1 }}"
|
||||
min-date="{{ minDate }}"
|
||||
bind:change="onChange"
|
||||
bind:input="onInput"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="选择日期(年月日)">
|
||||
<van-datetime-picker
|
||||
type="date"
|
||||
data-type="date"
|
||||
value="{{ currentDate2 }}"
|
||||
min-date="{{ minDate }}"
|
||||
bind:change="onChange"
|
||||
bind:input="onInput"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="选择日期(年月)">
|
||||
<van-datetime-picker
|
||||
type="year-month"
|
||||
data-type="year-month"
|
||||
value="{{ currentDate3 }}"
|
||||
min-date="{{ minDate }}"
|
||||
bind:change="onChange"
|
||||
bind:input="onInput"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="选择时间">
|
||||
<van-datetime-picker
|
||||
type="time"
|
||||
data-type="time"
|
||||
value="{{ currentDate4 }}"
|
||||
min-hour="{{ minHour }}"
|
||||
max-hour="{{ maxHour }}"
|
||||
bind:change="onChange"
|
||||
bind:input="onInput"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<van-toast id="van-toast" />
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-loading": "../loading/index"
|
||||
"van-picker": "../picker/index"
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import { isDef } from '../common/utils';
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
function isValidDate(date) {
|
||||
return isDef(date) && !isNaN(new Date(date).getTime())
|
||||
};
|
||||
return isDef(date) && !isNaN(new Date(date).getTime());
|
||||
}
|
||||
|
||||
function range(num, min, max) {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
@ -93,24 +93,8 @@ VantComponent({
|
||||
},
|
||||
|
||||
data: {
|
||||
pickerValue: [],
|
||||
innerValue: Date.now()
|
||||
},
|
||||
|
||||
computed: {
|
||||
columns() {
|
||||
const results = this.getRanges().map(({ type, range }) => {
|
||||
const values = times(range[1] - range[0] + 1, index => {
|
||||
let value = range[0] + index;
|
||||
value = type === 'year' ? `${value}` : padZero(value);
|
||||
return value;
|
||||
});
|
||||
|
||||
return values;
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
innerValue: Date.now(),
|
||||
columns: []
|
||||
},
|
||||
|
||||
watch: {
|
||||
@ -119,15 +103,51 @@ VantComponent({
|
||||
val = this.correctValue(val);
|
||||
const isEqual = val === data.innerValue;
|
||||
if (!isEqual) {
|
||||
this.set({ innerValue: val }, () => {
|
||||
this.updateColumnValue(val);
|
||||
this.updateColumnValue(val).then(() => {
|
||||
this.$emit('input', val);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
type: 'updateColumns',
|
||||
minHour: 'updateColumns',
|
||||
maxHour: 'updateColumns',
|
||||
minMinute: 'updateColumns',
|
||||
maxMinute: 'updateColumns'
|
||||
},
|
||||
|
||||
methods: {
|
||||
asyncSet(data) {
|
||||
return new Promise(resolve => {
|
||||
this.set(data, resolve);
|
||||
});
|
||||
},
|
||||
|
||||
getPicker() {
|
||||
if (this.picker == null) {
|
||||
const picker = (this.picker = this.selectComponent(
|
||||
'.van-datetime-picker'
|
||||
));
|
||||
const { setColumnValues } = picker;
|
||||
picker.setColumnValues = (...args) =>
|
||||
setColumnValues.apply(picker, [...args, false]);
|
||||
}
|
||||
return this.picker;
|
||||
},
|
||||
|
||||
updateColumns() {
|
||||
const results = this.getRanges().map(({ type, range }, index) => {
|
||||
const values = times(range[1] - range[0] + 1, index => {
|
||||
let value = range[0] + index;
|
||||
value = type === 'year' ? `${value}` : padZero(value);
|
||||
return value;
|
||||
});
|
||||
|
||||
return { values };
|
||||
});
|
||||
|
||||
return this.asyncSet({ columns: results });
|
||||
},
|
||||
|
||||
getRanges(): object[] {
|
||||
const { data } = this;
|
||||
if (data.type === 'time') {
|
||||
@ -143,8 +163,20 @@ VantComponent({
|
||||
];
|
||||
}
|
||||
|
||||
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', data.innerValue);
|
||||
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', data.innerValue);
|
||||
const {
|
||||
maxYear,
|
||||
maxDate,
|
||||
maxMonth,
|
||||
maxHour,
|
||||
maxMinute
|
||||
} = this.getBoundary('max', data.innerValue);
|
||||
const {
|
||||
minYear,
|
||||
minDate,
|
||||
minMonth,
|
||||
minHour,
|
||||
minMinute
|
||||
} = this.getBoundary('min', data.innerValue);
|
||||
|
||||
const result = [
|
||||
{
|
||||
@ -247,17 +279,17 @@ VantComponent({
|
||||
this.$emit('confirm', this.data.innerValue);
|
||||
},
|
||||
|
||||
onChange(event: Weapp.Event): void {
|
||||
onChange(): void {
|
||||
const { data } = this;
|
||||
const pickerValue = event.detail.value;
|
||||
const values = pickerValue
|
||||
.slice(0, data.columns.length)
|
||||
.map((value, index) => data.columns[index][value]);
|
||||
let value;
|
||||
|
||||
const picker = this.getPicker();
|
||||
|
||||
if (data.type === 'time') {
|
||||
value = values.join(':');
|
||||
const indexes = picker.getIndexes();
|
||||
value = `${indexes[0] + data.minHour}:${indexes[1] + data.minMinute}`;
|
||||
} else {
|
||||
const values = picker.getValues();
|
||||
const year = getTrueValue(values[0]);
|
||||
const month = getTrueValue(values[1]);
|
||||
const maxDate = getMonthEndDay(year, month);
|
||||
@ -276,82 +308,46 @@ VantComponent({
|
||||
}
|
||||
value = this.correctValue(value);
|
||||
|
||||
this.set({ innerValue: value }, () => {
|
||||
this.updateColumnValue(value);
|
||||
this.updateColumnValue(value).then(() => {
|
||||
this.$emit('input', value);
|
||||
this.$emit('change', this);
|
||||
this.$emit('change', picker);
|
||||
});
|
||||
},
|
||||
|
||||
getColumnValue(index) {
|
||||
return this.getValues()[index];
|
||||
},
|
||||
|
||||
setColumnValue(index, value) {
|
||||
const { pickerValue, columns } = this.data;
|
||||
pickerValue[index] = columns[index].indexOf(value);
|
||||
this.set({ pickerValue });
|
||||
},
|
||||
|
||||
getColumnValues(index) {
|
||||
return this.data.columns[index];
|
||||
},
|
||||
|
||||
setColumnValues(index, values) {
|
||||
const { columns } = this.data;
|
||||
columns[index] = values;
|
||||
this.set({ columns });
|
||||
},
|
||||
|
||||
getValues() {
|
||||
const { pickerValue, columns } = this.data;
|
||||
return pickerValue.map((value, index) => columns[index][value]);
|
||||
},
|
||||
|
||||
setValues(values) {
|
||||
const { columns } = this.data;
|
||||
this.set({
|
||||
pickerValue: values.map((value, index) => columns[index].indexOf(value))
|
||||
});
|
||||
},
|
||||
|
||||
updateColumnValue(value): void {
|
||||
updateColumnValue(value) {
|
||||
let values = [];
|
||||
const { data } = this;
|
||||
const { columns } = data;
|
||||
const picker = this.getPicker();
|
||||
|
||||
if (data.type === 'time') {
|
||||
const currentValue = value.split(':');
|
||||
values = [
|
||||
columns[0].indexOf(currentValue[0]),
|
||||
columns[1].indexOf(currentValue[1])
|
||||
];
|
||||
const pair = value.split(':');
|
||||
values = [pair[0], pair[1]];
|
||||
} else {
|
||||
const date = new Date(value);
|
||||
values = [
|
||||
columns[0].indexOf(`${date.getFullYear()}`),
|
||||
columns[1].indexOf(padZero(date.getMonth() + 1))
|
||||
];
|
||||
values = [`${date.getFullYear()}`, padZero(date.getMonth() + 1)];
|
||||
if (data.type === 'date') {
|
||||
values.push(columns[2].indexOf(padZero(date.getDate())));
|
||||
values.push(padZero(date.getDate()));
|
||||
}
|
||||
if (data.type === 'datetime') {
|
||||
values.push(
|
||||
columns[2].indexOf(padZero(date.getDate())),
|
||||
columns[3].indexOf(padZero(date.getHours())),
|
||||
columns[4].indexOf(padZero(date.getMinutes()))
|
||||
padZero(date.getDate()),
|
||||
padZero(date.getHours()),
|
||||
padZero(date.getMinutes())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.set({ pickerValue: values });
|
||||
return this.asyncSet({ innerValue: value })
|
||||
.then(() => this.updateColumns())
|
||||
.then(() => {
|
||||
picker.setValues(values);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
const innerValue = this.correctValue(this.data.value);
|
||||
this.set({ innerValue }, () => {
|
||||
this.updateColumnValue(innerValue);
|
||||
this.updateColumnValue(innerValue).then(() => {
|
||||
this.$emit('input', innerValue);
|
||||
});
|
||||
}
|
||||
|
@ -1,34 +1,13 @@
|
||||
<view class="van-picker">
|
||||
<view wx:if="{{ showToolbar }}" class="van-picker__toolbar van-hairline--bottom">
|
||||
<view class="van-picker__cancel" bindtap="onCancel">{{ cancelButtonText }}</view>
|
||||
<view class="van-picker__title">{{ title }}</view>
|
||||
<view class="van-picker__confirm" bindtap="onConfirm">{{ confirmButtonText }}</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{ loading }}" class="van-picker__loading">
|
||||
<van-loading color="#1989fa"/>
|
||||
</view>
|
||||
|
||||
<picker-view
|
||||
indicator-style="height: {{ itemHeight }}px;"
|
||||
style="width: 100%; height: {{ itemHeight * visibleItemCount + 'px' }}"
|
||||
bindchange="onChange"
|
||||
value="{{ pickerValue }}"
|
||||
class="van-picker__columns"
|
||||
>
|
||||
<picker-view-column
|
||||
wx:for="{{ columns }}"
|
||||
wx:for-item="row"
|
||||
wx:for-index="rowIndex"
|
||||
wx:key="rowIndex"
|
||||
class="van-picker-column"
|
||||
>
|
||||
<view
|
||||
wx:for="{{ row }}"
|
||||
wx:key="{{ item }}"
|
||||
style="line-height: {{ itemHeight }}px;"
|
||||
class="van-picker-column__item {{ index === pickerValue[rowIndex] ? 'van-picker-column__item--selected' : '' }}"
|
||||
>{{ item }}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
<van-picker
|
||||
class="van-datetime-picker"
|
||||
title="{{ title }}"
|
||||
columns="{{ columns }}"
|
||||
item-height="{{ itemHeight }}"
|
||||
show-toolbar="{{ showToolbar }}"
|
||||
visible-item-count="{{ visibleItemCount }}"
|
||||
confirm-button-text="{{ confirmButtonText }}"
|
||||
cancel-button-text="{{ cancelButtonText }}"
|
||||
bind:change="onChange"
|
||||
bind:confirm="onConfirm"
|
||||
bind:cancel="onCancel"
|
||||
/>
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { VantComponent } from '../common/component';
|
||||
|
||||
function isSimple(columns) {
|
||||
return columns.length && !columns[0].values;
|
||||
}
|
||||
|
||||
VantComponent({
|
||||
classes: ['active-class', 'toolbar-class', 'column-class'],
|
||||
|
||||
@ -25,15 +29,12 @@ VantComponent({
|
||||
type: Array,
|
||||
value: [],
|
||||
observer(columns = []) {
|
||||
this.set({
|
||||
simple: columns.length && !columns[0].values
|
||||
}, () => {
|
||||
const children = this.children = this.selectAllComponents('.van-picker__column');
|
||||
this.simple = isSimple(columns);
|
||||
const children = this.children = this.selectAllComponents('.van-picker__column');
|
||||
|
||||
if (Array.isArray(children) && children.length) {
|
||||
this.setColumns();
|
||||
}
|
||||
});
|
||||
if (Array.isArray(children) && children.length) {
|
||||
this.setColumns();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -47,7 +48,7 @@ VantComponent({
|
||||
|
||||
setColumns() {
|
||||
const { data } = this;
|
||||
const columns = data.simple ? [{ values: data.columns }] : data.columns;
|
||||
const columns = this.simple ? [{ values: data.columns }] : data.columns;
|
||||
columns.forEach((columns, index: number) => {
|
||||
this.setColumnValues(index, columns.values);
|
||||
});
|
||||
@ -55,7 +56,7 @@ VantComponent({
|
||||
|
||||
emit(event: Weapp.Event) {
|
||||
const { type } = event.currentTarget.dataset;
|
||||
if (this.data.simple) {
|
||||
if (this.simple) {
|
||||
this.$emit(type, {
|
||||
value: this.getColumnValue(0),
|
||||
index: this.getColumnIndex(0)
|
||||
@ -69,7 +70,7 @@ VantComponent({
|
||||
},
|
||||
|
||||
onChange(event: Weapp.Event) {
|
||||
if (this.data.simple) {
|
||||
if (this.simple) {
|
||||
this.$emit('change', {
|
||||
picker: this,
|
||||
value: this.getColumnValue(0),
|
||||
@ -118,7 +119,7 @@ VantComponent({
|
||||
},
|
||||
|
||||
// set options of column by index
|
||||
setColumnValues(index: number, options: any[]) {
|
||||
setColumnValues(index: number, options: any[], needReset = true) {
|
||||
const column = this.children[index];
|
||||
|
||||
if (
|
||||
@ -126,7 +127,9 @@ VantComponent({
|
||||
JSON.stringify(column.data.options) !== JSON.stringify(options)
|
||||
) {
|
||||
column.set({ options }, () => {
|
||||
column.setIndex(0);
|
||||
if (needReset) {
|
||||
column.setIndex(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -21,12 +21,12 @@
|
||||
>
|
||||
<picker-column
|
||||
class="van-picker__column"
|
||||
wx:for="{{ simple ? [columns] : columns }}"
|
||||
wx:key="index"
|
||||
wx:for="{{ isSimple(columns) ? [columns] : columns }}"
|
||||
wx:key="{{ index }}"
|
||||
data-index="{{ index }}"
|
||||
custom-class="column-class"
|
||||
value-key="{{ valueKey }}"
|
||||
initial-options="{{ simple ? item : item.values }}"
|
||||
initial-options="{{ isSimple(columns) ? item : item.values }}"
|
||||
default-index="{{ item.defaultIndex }}"
|
||||
item-height="{{ itemHeight }}"
|
||||
visible-item-count="{{ visibleItemCount }}"
|
||||
@ -39,3 +39,10 @@
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<wxs module="isSimple">
|
||||
function isSimple(columns) {
|
||||
return columns.length && !columns[0].values;
|
||||
}
|
||||
module.exports = isSimple;
|
||||
</wxs>
|
||||
|
Loading…
x
Reference in New Issue
Block a user