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