diff --git a/document/components/docs/zh-CN/time-picker.md b/document/components/docs/zh-CN/time-picker.md index 29b9c0280254a2aba22ca250aa66933706a37347..2455d1c31bdda6e2fb596926a06c8d9ad3d73099 100644 --- a/document/components/docs/zh-CN/time-picker.md +++ b/document/components/docs/zh-CN/time-picker.md @@ -126,6 +126,49 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请 } ``` +- 分钟数的步长 + + 通过 `minuteStep` 属性可配置分钟数的步长,默认为 10 分钟,这样的话,可选的分钟就是 10、20、30、40、50。另外在 v1.10.5+,`minuteStep` 还支持传入一个对象,你可以通过子属性 `rule` 配置取整的规则,是向上取整 `ceil`,向下取整 `floor`,又或是四舍五入`round`。而子属性 `step` 则代表步长。 + + ```html + Config minute step + ``` + + ```js + export default { + methods: { + showFormatPicker() { + if (!this.minuteStepPicker) { + this.minuteStepPicker = this.$createTimePicker({ + minuteStep: { + rule: 'ceil', + step: 15 + }, + onSelect: this.selectHandler, + onCancel: this.cancelHandler + }) + } + this.minuteStepPicker.show() + }, + selectHandler(selectedTime, selectedText, formatedTime) { + this.$createDialog({ + type: 'warn', + title: `selected time: ${selectedTime}`, + content: `selected text: ${selectedText}
format time: ${formatedTime}`, + icon: 'cubeic-alert' + }).show() + }, + cancelHandler() { + this.$createToast({ + type: 'correct', + txt: 'Picker canceled', + time: 1000 + }).show() + } + } + } + ``` + - 手动设置时间 ```html TimePicker - setTime(next hour) @@ -177,7 +220,7 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请 | delay | 将当前时间向后推算的分钟数,决定了最小可选时间 | Number | 15 | | day | 日期配置 | Object | { len: 3, filter: ['今日'], format: 'M月D日' } | | showNow | 是否显示现在;以及现在选项的文案1.9.0 | Boolean, Object1.9.0 | true | -| minuteStep | 分钟数的步长 | Number | 10 | +| minuteStep | 分钟数的步长。 当为 Object 时还可以配置取整规则,详见后续 `minuteStep` 子配置项说明1.10.5 | Number, Object1.10.5 | 10 | | title | 标题 | String | '选择时间' | | subtitle1.8.1 | 副标题 | String | '' | | cancelTxt1.8.1 | 取消按钮文案 | String | '取消' | @@ -195,11 +238,18 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请 | filter | 日期列,将时间映射为filter中的文案内容 | Array | ['今日'] | | format | 时间格式化 | String | 'M月D日' | -* `showNow` 子配置项 +* `showNow` 子配置项1.9.0 | 参数 | 说明 | 类型 | 默认值 | | - | - | - | - | -| text1.9.0 | 现在选项的文案 | String | '现在' | +| text | 现在选项的文案 | String | '现在' | + +* `minuteStep` 子配置项1.10.5 + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +| - | - | - | - | - | +| rule | 取整的规则 | String | floor/ceil/round | 'floor' | +| step | 分钟数的步长 | Number | - | 10 | ### 事件 diff --git a/example/pages/time-picker.vue b/example/pages/time-picker.vue index d7c04742ad8afa8e3cc8bade4bb91a6b4afc1417..2c780ed4b9885323f4d2a09d08aa7fbc8ab1e3bf 100644 --- a/example/pages/time-picker.vue +++ b/example/pages/time-picker.vue @@ -5,6 +5,7 @@ TimePicker Config day options Config format + Config minute step Use setTime @@ -55,6 +56,19 @@ } this.formatPicker.show() }, + showMinuteStepPicker() { + if (!this.minuteStepPicker) { + this.minuteStepPicker = this.$createTimePicker({ + minuteStep: { + rule: 'ceil', + step: 15 + }, + onSelect: this.selectHandler, + onCancel: this.cancelHandler + }) + } + this.minuteStepPicker.show() + }, showSetTimePiker() { if (!this.setTimePiker) { this.setTimePiker = this.$createTimePicker({ diff --git a/src/components/time-picker/time-picker.vue b/src/components/time-picker/time-picker.vue index ed42e46970620d6807a4619c83caedf296d1f715..082d690f0f1de13fbd342e7944070ad7375e3698 100644 --- a/src/components/time-picker/time-picker.vue +++ b/src/components/time-picker/time-picker.vue @@ -42,6 +42,14 @@ defaultText: '现在' } + const INT_RULE = { + floor: 'floor', + ceil: 'ceil', + round: 'round' + } + + const DEFAULT_STEP = 10 + export default { name: COMPONENT_NAME, mixins: [visibilityMixin, popupMixin, pickerMixin], @@ -72,8 +80,8 @@ default: true }, minuteStep: { - type: Number, - default: 10 + type: [Number, Object], + default: DEFAULT_STEP }, format: { type: String, @@ -91,8 +99,25 @@ nowText() { return (this.showNow && this.showNow.text) || NOW.defaultText }, + minuteStepRule() { + const minuteStep = this.minuteStep + return (typeof minuteStep === 'object' && Math[INT_RULE[minuteStep.rule]]) || Math[INT_RULE.floor] + }, + minuteStepNumber() { + const minuteStep = this.minuteStep + return typeof minuteStep === 'number' ? minuteStep : (minuteStep.step || DEFAULT_STEP) + }, minTime() { - return new Date(+this.now + this.delay * MINUTE_TIMESTAMP) + let minTimeStamp = +this.now + this.delay * MINUTE_TIMESTAMP + + // Handle the minTime selectable change caused by minute step. + const minute = new Date(minTimeStamp).getMinutes() + const intMinute = this.minuteStepRule(minute / this.minuteStepNumber) * this.minuteStepNumber + if (intMinute >= 60) { + minTimeStamp += (60 - minute) * MINUTE_TIMESTAMP + } + + return new Date(minTimeStamp) }, days() { const days = [] @@ -133,7 +158,7 @@ }, minutes() { const minutes = [] - for (let i = 0; i < 60; i += this.minuteStep) { + for (let i = 0; i < 60; i += this.minuteStepNumber) { minutes.push({ value: i, text: pad(i) + '分' @@ -142,7 +167,7 @@ return minutes }, partMinutes() { - const begin = Math.floor(this.minTime.getMinutes() / this.minuteStep) + const begin = this.minuteStepRule(this.minTime.getMinutes() / this.minuteStepNumber) return this.minutes.slice(begin) }, cascadeData() { @@ -192,9 +217,9 @@ const hourIndex = hour - beginHour // calculate minuteIndex - const minute = Math.floor(valueDate.getMinutes() / this.minuteStep) + const minute = this.minuteStepRule(valueDate.getMinutes() / this.minuteStepNumber) const beginMinute = !dayIndex && (this.showNow ? hourIndex === 1 : !hourIndex) - ? Math.floor(this.minTime.getMinutes() / this.minuteStep) + ? this.minuteStepRule(this.minTime.getMinutes() / this.minuteStepNumber) : 0 const minuteIndex = minute - beginMinute diff --git a/test/unit/specs/time-picker.spec.js b/test/unit/specs/time-picker.spec.js index 62720610ef532a181c36967e8073b76566098e18..e9c50febd1c2d429c3ca6dac24978cb3281be479 100644 --- a/test/unit/specs/time-picker.spec.js +++ b/test/unit/specs/time-picker.spec.js @@ -233,6 +233,45 @@ describe('TimePicker', () => { .to.equal(1) console.warn = originWarn }) + + testMinuteStep() + + function testMinuteStep() { + const minuteStepConfigs = [ + undefined, + 15, { + rule: 'ceil' + }, { + step: 15 + }, { + rule: 'floor', + step: 5 + }, { + rule: 'ceil', + step: 8 + }, { + rule: 'round', + step: 10 + } + ] + + minuteStepConfigs.forEach((item) => { + it(`should init minutes correct when minute step is ${item}`, function () { + vm = createPicker({ + showNow: false, + delay: 0, + minuteStep: item, + format: 'h:m' + }) + + const step = (typeof item === 'number' ? item : (item && item.step)) || 10 + const rule = (item && item.rule) || 'floor' + + expect(vm.partMinutes[0].value) + .to.equal(Math[rule](vm.minTime.getMinutes() / step) * step) + }) + }) + } }) function createPicker(props = {}, events = {}) {