mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-08-06 21:39:45 +08:00
feat(DatetimePicker): add new component datetime-picker @rex-zsd (#881)
This commit is contained in:
parent
ccaee67072
commit
237fccadca
@ -34,7 +34,8 @@
|
||||
"pages/radio/index",
|
||||
"pages/checkbox/index",
|
||||
"pages/goods-action/index",
|
||||
"pages/swipe-cell/index"
|
||||
"pages/swipe-cell/index",
|
||||
"pages/datetime-picker/index"
|
||||
],
|
||||
"window": {
|
||||
"navigationBarBackgroundColor": "#f8f8f8",
|
||||
@ -87,6 +88,7 @@
|
||||
"van-tag": "../../dist/tag/index",
|
||||
"van-toast": "../../dist/toast/index",
|
||||
"van-transition": "../../dist/transition/index",
|
||||
"van-tree-select": "../../dist/tree-select/index"
|
||||
"van-tree-select": "../../dist/tree-select/index",
|
||||
"van-datetime-picker": "../../dist/datetime-picker/index"
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,10 @@ export default [
|
||||
path: '/action-sheet',
|
||||
title: 'ActionSheet 上拉菜单'
|
||||
},
|
||||
{
|
||||
path: '/datetime-picker',
|
||||
title: 'DatetimePicker 时间选择'
|
||||
},
|
||||
{
|
||||
path: '/dialog',
|
||||
title: 'Dialog 弹出框'
|
||||
|
20
example/pages/datetime-picker/index.js
Normal file
20
example/pages/datetime-picker/index.js
Normal file
@ -0,0 +1,20 @@
|
||||
import Page from '../../common/page';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
minHour: 10,
|
||||
maxHour: 20,
|
||||
minDate: new Date(2018, 0, 1).getTime(),
|
||||
maxDate: new Date(2019, 10, 1).getTime(),
|
||||
currentDate1: new Date(2018, 2, 1).getTime(),
|
||||
currentDate2: null,
|
||||
currentDate3: new Date(2018, 0, 1),
|
||||
currentDate4: '12:00',
|
||||
loading: false
|
||||
},
|
||||
|
||||
onChange(event) {
|
||||
const picker = event.detail;
|
||||
console.log(event);
|
||||
}
|
||||
});
|
3
example/pages/datetime-picker/index.json
Normal file
3
example/pages/datetime-picker/index.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"navigationBarTitleText": "DatetimePicker 时间选择"
|
||||
}
|
38
example/pages/datetime-picker/index.wxml
Normal file
38
example/pages/datetime-picker/index.wxml
Normal file
@ -0,0 +1,38 @@
|
||||
<demo-block title="选择完整时间">
|
||||
<van-datetime-picker
|
||||
loading="{{ loading }}"
|
||||
show-toolbar="{{ false }}"
|
||||
value="{{ currentDate1 }}"
|
||||
bind:change="onChange"
|
||||
type="datetime"
|
||||
min-date="{{ minDate }}"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="选择日期(年月日)">
|
||||
<van-datetime-picker
|
||||
value="{{ currentDate2 }}"
|
||||
bind:change="onChange"
|
||||
type="date"
|
||||
min-date="{{ minDate }}"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="选择日期(年月)">
|
||||
<van-datetime-picker
|
||||
value="{{ currentDate3 }}"
|
||||
bind:change="onChange"
|
||||
type="year-month"
|
||||
min-date="{{ minDate }}"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="选择时间">
|
||||
<van-datetime-picker
|
||||
value="{{ currentDate4 }}"
|
||||
bind:change="onChange"
|
||||
type="time"
|
||||
min-hour="{{ minHour }}"
|
||||
max-hour="{{ maxHour }}"
|
||||
/>
|
||||
</demo-block>
|
1
example/pages/datetime-picker/index.wxss
Normal file
1
example/pages/datetime-picker/index.wxss
Normal file
@ -0,0 +1 @@
|
||||
|
159
packages/datetime-picker/README.md
Normal file
159
packages/datetime-picker/README.md
Normal file
@ -0,0 +1,159 @@
|
||||
## DatetimePicker 时间选择
|
||||
时间选择组件通常与 [弹出层](#/popup) 组件配合使用
|
||||
|
||||
### 使用指南
|
||||
在 app.json 或 index.json 中引入组件
|
||||
```json
|
||||
"usingComponents": {
|
||||
"van-datetime-picker": "path/to/vant-weapp/dist/datetime-picker/index"
|
||||
}
|
||||
```
|
||||
|
||||
### 代码演示
|
||||
|
||||
#### 选择完整时间
|
||||
|
||||
```html
|
||||
<van-datetime-picker
|
||||
value="{{ currentDate }}"
|
||||
bind:change="onChange"
|
||||
type="datetime"
|
||||
min-date="{{ minDate }}"
|
||||
max-date="{{ maxDate }}"
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
Page({
|
||||
data: {
|
||||
minHour: 10,
|
||||
maxHour: 20,
|
||||
minDate: new Date(),
|
||||
maxDate: new Date(2019, 10, 1),
|
||||
currentDate: new Date()
|
||||
},
|
||||
onChange(event) {
|
||||
this.setData({
|
||||
currentDate: event.detail.value
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 选择日期(年月日)
|
||||
|
||||
```html
|
||||
<van-datetime-picker
|
||||
value="{{ currentDate }}"
|
||||
bind:change="onChange"
|
||||
type="date"
|
||||
min-date="{{ minDate }}"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
Page({
|
||||
data: {
|
||||
currentDate: new Date(),
|
||||
minDate: new Date()
|
||||
},
|
||||
onChange(event) {
|
||||
this.setData({
|
||||
currentDate: event.detail.value
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 选择日期(年月)
|
||||
|
||||
```html
|
||||
<van-datetime-picker
|
||||
value="{{ currentDate }}"
|
||||
bind:change="onChange"
|
||||
type="year-month"
|
||||
min-date="{{ minDate }}"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
Page({
|
||||
data: {
|
||||
currentDate: new Date(),
|
||||
minDate: new Date()
|
||||
},
|
||||
onChange(event) {
|
||||
this.setData({
|
||||
currentDate: event.detail.value
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 选择时间
|
||||
|
||||
```html
|
||||
<van-datetime-picker
|
||||
value="{{ currentDate }}"
|
||||
bind:change="onChange"
|
||||
type="time"
|
||||
min-hour="{{ minHour }}"
|
||||
max-hour="{{ maxHour }}"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
Page({
|
||||
data: {
|
||||
currentDate: '12:00',
|
||||
minHour: 9,
|
||||
maxHour: 23
|
||||
},
|
||||
onChange(event) {
|
||||
this.setData({
|
||||
currentDate: event.detail.value
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|------|------|
|
||||
| type | 类型,可选值为 `date` <br> `time` `year-month` | `String` | `datetime` |
|
||||
| min-date | 可选的最小时间,精确到分钟 | `Date` | 十年前 |
|
||||
| max-date | 可选的最大时间,精确到分钟 | `Date` | 十年后 |
|
||||
| min-hour | 可选的最小小时,针对 time 类型 | `Number` | `0` |
|
||||
| max-hour | 可选的最大小时,针对 time 类型 | `Number` | `23` |
|
||||
| min-minute | 可选的最小分钟,针对 time 类型 | `Number` | `0` |
|
||||
| max-minute | 可选的最大分钟,针对 time 类型 | `Number` | `59` |
|
||||
| title | 顶部栏标题 | `String` | `''` |
|
||||
| show-toolbar | 是否显示顶部栏 | `Boolean` | `false` |
|
||||
| loading | 是否显示加载状态 | `Boolean` | `false` |
|
||||
| item-height | 选项高度 | `Number` | `44` |
|
||||
| confirm-button-text | 确认按钮文字 | `String` | `确认` |
|
||||
| cancel-button-text | 取消按钮文字 | `String` | `取消` |
|
||||
| visible-item-count | 可见的选项个数 | `Number` | `5` |
|
||||
|
||||
### Event
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
|------|------|------|
|
||||
| input | 当值变化时触发的事件 | 当前 value |
|
||||
| change | 当值变化时触发的事件 | 组件实例 |
|
||||
| confirm | 点击完成按钮时触发的事件 | 当前 value |
|
||||
| cancel | 点击取消按钮时触发的事件 | - |
|
||||
|
||||
### change事件
|
||||
|
||||
在`change`事件中,可以获取到组件实例,对组件进行相应的更新等操作:
|
||||
|
||||
| 函数 | 说明 |
|
||||
|------|------|
|
||||
| getColumnValue(index) | 获取对应列中选中的值 |
|
||||
| setColumnValue(index, value) | 设置对应列中选中的值 |
|
||||
| getColumnValues(index) | 获取对应列中所有的备选值 |
|
||||
| setColumnValues(index, values) | 设置对应列中所有的备选值 |
|
||||
| getValues() | 获取所有列中被选中的值,返回一个数组 |
|
||||
| setValues(values) | `values`为一个数组,设置所有列中被选中的值 |
|
6
packages/datetime-picker/index.json
Normal file
6
packages/datetime-picker/index.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-loading": "../loading/index"
|
||||
}
|
||||
}
|
72
packages/datetime-picker/index.less
Normal file
72
packages/datetime-picker/index.less
Normal file
@ -0,0 +1,72 @@
|
||||
@import '../common/style/var.less';
|
||||
|
||||
.van-picker {
|
||||
-webkit-text-size-adjust: 100%; /* avoid iOS text size adjust */
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-color: @white;
|
||||
user-select: none;
|
||||
|
||||
&__toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
&__cancel,
|
||||
&__confirm {
|
||||
color: @blue;
|
||||
padding: 0 15px;
|
||||
font-size: 14px;
|
||||
|
||||
&:active {
|
||||
background-color: @active-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
max-width: 50%;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__columns {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__loading {
|
||||
display: flex;
|
||||
z-index: 4;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(255, 255, 255, .9);
|
||||
}
|
||||
|
||||
&-column {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
|
||||
&__item {
|
||||
padding: 0 5px;
|
||||
color: @gray-dark;
|
||||
|
||||
&--selected {
|
||||
font-weight: 500;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
opacity: .3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
356
packages/datetime-picker/index.ts
Normal file
356
packages/datetime-picker/index.ts
Normal file
@ -0,0 +1,356 @@
|
||||
import { VantComponent } from '../common/component';
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const isValidDate = date => !isNaN(new Date(date).getTime());
|
||||
|
||||
function range(num, min, max) {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
}
|
||||
|
||||
VantComponent({
|
||||
props: {
|
||||
value: null,
|
||||
title: String,
|
||||
loading: Boolean,
|
||||
itemHeight: {
|
||||
type: Number,
|
||||
value: 44
|
||||
},
|
||||
visibleItemCount: {
|
||||
type: Number,
|
||||
value: 5
|
||||
},
|
||||
confirmButtonText: {
|
||||
type: String,
|
||||
value: '确认'
|
||||
},
|
||||
cancelButtonText: {
|
||||
type: String,
|
||||
value: '取消'
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
value: 'datetime'
|
||||
},
|
||||
showToolbar: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
minDate: {
|
||||
type: Number,
|
||||
value: new Date(currentYear - 10, 0, 1).getTime()
|
||||
},
|
||||
maxDate: {
|
||||
type: Number,
|
||||
value: new Date(currentYear + 10, 11, 31).getTime()
|
||||
},
|
||||
minHour: {
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
maxHour: {
|
||||
type: Number,
|
||||
value: 23
|
||||
},
|
||||
minMinute: {
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
maxMinute: {
|
||||
type: Number,
|
||||
value: 59
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
pickerValue: [],
|
||||
innerValue: Date.now()
|
||||
},
|
||||
|
||||
computed: {
|
||||
columns() {
|
||||
const results = this.getRanges().map(({ type, range }) => {
|
||||
const values = this.times(range[1] - range[0] + 1, index => {
|
||||
let value = range[0] + index;
|
||||
value = type === 'year' ? `${value}` : this.pad(value);
|
||||
return value;
|
||||
});
|
||||
|
||||
return values;
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(val) {
|
||||
const { data } = this;
|
||||
val = this.correctValue(val);
|
||||
const isEqual = val === data.innerValue;
|
||||
if (!isEqual) {
|
||||
this.setData({ innerValue: val }, () => {
|
||||
this.updateColumnValue(val);
|
||||
this.$emit('input', val);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getRanges(): object[] {
|
||||
const { data } = this;
|
||||
if (data.type === 'time') {
|
||||
return [
|
||||
{
|
||||
type: 'hour',
|
||||
range: [data.minHour, data.maxHour]
|
||||
},
|
||||
{
|
||||
type: 'minute',
|
||||
range: [data.minMinute, data.maxMinute]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', data.innerValue);
|
||||
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', data.innerValue);
|
||||
|
||||
const result = [
|
||||
{
|
||||
type: 'year',
|
||||
range: [minYear, maxYear]
|
||||
},
|
||||
{
|
||||
type: 'month',
|
||||
range: [minMonth, maxMonth]
|
||||
},
|
||||
{
|
||||
type: 'day',
|
||||
range: [minDate, maxDate]
|
||||
},
|
||||
{
|
||||
type: 'hour',
|
||||
range: [minHour, maxHour]
|
||||
},
|
||||
{
|
||||
type: 'minute',
|
||||
range: [minMinute, maxMinute]
|
||||
}
|
||||
];
|
||||
|
||||
if (data.type === 'date') result.splice(3, 2);
|
||||
if (data.type === 'year-month') result.splice(2, 3);
|
||||
return result;
|
||||
},
|
||||
|
||||
pad(val: string | number): string {
|
||||
return `00${val}`.slice(-2);
|
||||
},
|
||||
|
||||
correctValue(value) {
|
||||
const { data, pad } = this;
|
||||
// validate value
|
||||
const isDateType = data.type !== 'time';
|
||||
if (isDateType && !isValidDate(value)) {
|
||||
value = data.minDate;
|
||||
} else if (!isDateType && !value) {
|
||||
const { minHour } = data;
|
||||
value = `${pad(minHour)}:00`;
|
||||
}
|
||||
|
||||
// time type
|
||||
if (!isDateType) {
|
||||
let [hour, minute] = value.split(':');
|
||||
hour = pad(range(hour, data.minHour, data.maxHour));
|
||||
minute = pad(range(minute, data.minMinute, data.maxMinute));
|
||||
|
||||
return `${hour}:${minute}`;
|
||||
}
|
||||
|
||||
// date type
|
||||
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', value);
|
||||
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', value);
|
||||
const minDay = new Date(minYear, minMonth - 1, minDate, minHour, minMinute);
|
||||
const maxDay = new Date(maxYear, maxMonth - 1, maxDate, maxHour, maxMinute);
|
||||
value = Math.max(value, minDay.getTime());
|
||||
value = Math.min(value, maxDay.getTime());
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
times(n: number, iteratee: (number) => string): string[] {
|
||||
let index = -1;
|
||||
const result = Array(n);
|
||||
|
||||
while (++index < n) {
|
||||
result[index] = iteratee(index);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
getBoundary(type: string, innerValue: number): object {
|
||||
const value = new Date(innerValue);
|
||||
const boundary = new Date(this.data[`${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 = boundary.getDate();
|
||||
if (value.getDate() === date) {
|
||||
hour = boundary.getHours();
|
||||
if (value.getHours() === hour) {
|
||||
minute = boundary.getMinutes();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
[`${type}Year`]: year,
|
||||
[`${type}Month`]: month,
|
||||
[`${type}Date`]: date,
|
||||
[`${type}Hour`]: hour,
|
||||
[`${type}Minute`]: minute
|
||||
};
|
||||
},
|
||||
|
||||
getTrueValue(formattedValue: string): number {
|
||||
if (!formattedValue) return;
|
||||
while (isNaN(parseInt(formattedValue, 10))) {
|
||||
formattedValue = formattedValue.slice(1);
|
||||
}
|
||||
return parseInt(formattedValue, 10);
|
||||
},
|
||||
|
||||
getMonthEndDay(year, month): number {
|
||||
return 32 - new Date(year, month - 1, 32).getDate();
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.$emit('cancel');
|
||||
},
|
||||
|
||||
onConfirm(): void {
|
||||
this.$emit('confirm', this.data.innerValue);
|
||||
},
|
||||
|
||||
onChange(event: Weapp.Event): void {
|
||||
const { data } = this;
|
||||
const pickerValue = event.detail.value;
|
||||
const values = pickerValue.map((value, index) => data.columns[index][value]);
|
||||
let value;
|
||||
|
||||
if (data.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]);
|
||||
if (data.type === 'year-month') {
|
||||
date = 1;
|
||||
}
|
||||
date = date > maxDate ? maxDate : date;
|
||||
let hour = 0;
|
||||
let minute = 0;
|
||||
if (data.type === 'datetime') {
|
||||
hour = this.getTrueValue(values[3]);
|
||||
minute = this.getTrueValue(values[4]);
|
||||
}
|
||||
value = new Date(year, month - 1, date, hour, minute);
|
||||
}
|
||||
value = this.correctValue(value);
|
||||
|
||||
this.setData({ innerValue: value }, () => {
|
||||
this.updateColumnValue(value);
|
||||
this.$emit('input', value);
|
||||
this.$emit('change', this);
|
||||
});
|
||||
},
|
||||
|
||||
getColumnValue(index) {
|
||||
return this.getValues()[index];
|
||||
},
|
||||
|
||||
setColumnValue(index, value) {
|
||||
const { pickerValue, columns } = this.data;
|
||||
pickerValue[index] = columns[index].indexOf(value);
|
||||
this.setData({ pickerValue });
|
||||
},
|
||||
|
||||
getColumnValues(index) {
|
||||
return this.data.columns[index];
|
||||
},
|
||||
|
||||
setColumnValues(index, values) {
|
||||
const { columns } = this.data;
|
||||
columns[index] = values;
|
||||
this.setData({ columns });
|
||||
},
|
||||
|
||||
getValues() {
|
||||
const { pickerValue, columns } = this.data;
|
||||
return pickerValue.map((value, index) => columns[index][value])
|
||||
},
|
||||
|
||||
setValues(values) {
|
||||
const { columns } = this.data;
|
||||
this.setData({
|
||||
pickerValue: values.map((value, index) => columns[index].indexOf(value))
|
||||
});
|
||||
},
|
||||
|
||||
updateColumnValue(value): void {
|
||||
let values = [];
|
||||
const { pad, data } = this;
|
||||
const { columns } = data;
|
||||
|
||||
if (data.type === 'time') {
|
||||
const currentValue = value.split(':');
|
||||
values = [
|
||||
columns[0].indexOf(currentValue[0]),
|
||||
columns[1].indexOf(currentValue[1])
|
||||
];
|
||||
} else {
|
||||
const date = new Date(value);
|
||||
values = [
|
||||
columns[0].indexOf(`${date.getFullYear()}`),
|
||||
columns[1].indexOf(pad(date.getMonth() + 1))
|
||||
];
|
||||
if (data.type === 'date') {
|
||||
values.push(columns[2].indexOf(pad(date.getDate())));
|
||||
}
|
||||
if (data.type === 'datetime') {
|
||||
values.push(
|
||||
columns[2].indexOf(pad(date.getDate())),
|
||||
columns[3].indexOf(pad(date.getHours())),
|
||||
columns[4].indexOf(pad(date.getMinutes()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.setData({ pickerValue: values });
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
const innerValue = this.correctValue(this.data.value);
|
||||
this.setData({ innerValue }, () => {
|
||||
this.updateColumnValue(innerValue);
|
||||
this.$emit('input', innerValue);
|
||||
});
|
||||
}
|
||||
});
|
34
packages/datetime-picker/index.wxml
Normal file
34
packages/datetime-picker/index.wxml
Normal file
@ -0,0 +1,34 @@
|
||||
<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>
|
Loading…
x
Reference in New Issue
Block a user