Commit 456877a16553e1d50b5e3f91ef38f74616ffba8c
1 parent
0fd13696
update TimePicker
update TimePicker
Showing
6 changed files
with
268 additions
and
19 deletions
Show diff stats
assets/iview.png
| 1 | +<template> | |
| 2 | + <div :class="classes"> | |
| 3 | + <div :class="[prefixCls + '-body']"> | |
| 4 | + <div :class="[prefixCls + '-content', prefixCls + '-content-left']"> | |
| 5 | + <div :class="[timePrefixCls + '-header']">开始时间</div> | |
| 6 | + <time-spinner | |
| 7 | + :show-seconds="showSeconds" | |
| 8 | + :hours="hours" | |
| 9 | + :minutes="minutes" | |
| 10 | + :seconds="seconds" | |
| 11 | + :disabled-hours="disabledHours" | |
| 12 | + :disabled-minutes="disabledMinutes" | |
| 13 | + :disabled-seconds="disabledSeconds" | |
| 14 | + :hide-disabled-options="hideDisabledOptions" | |
| 15 | + @on-change="handleStartChange" | |
| 16 | + @on-pick-click="handlePickClick"></time-spinner> | |
| 17 | + </div> | |
| 18 | + <div :class="[prefixCls + '-content', prefixCls + '-content-right']"> | |
| 19 | + <div :class="[timePrefixCls + '-header']">结束时间</div> | |
| 20 | + <time-spinner | |
| 21 | + :show-seconds="showSeconds" | |
| 22 | + :hours="hoursEnd" | |
| 23 | + :minutes="minutesEnd" | |
| 24 | + :seconds="secondsEnd" | |
| 25 | + :disabled-hours="disabledHours" | |
| 26 | + :disabled-minutes="disabledMinutes" | |
| 27 | + :disabled-seconds="disabledSeconds" | |
| 28 | + :hide-disabled-options="hideDisabledOptions" | |
| 29 | + @on-change="handleEndChange" | |
| 30 | + @on-pick-click="handlePickClick"></time-spinner> | |
| 31 | + </div> | |
| 32 | + <Confirm | |
| 33 | + @on-pick-clear="handlePickClear" | |
| 34 | + @on-pick-success="handlePickSuccess"></Confirm> | |
| 35 | + </div> | |
| 36 | + </div> | |
| 37 | +</template> | |
| 38 | +<script> | |
| 39 | + import TimeSpinner from '../base/time-spinner.vue'; | |
| 40 | + import Confirm from '../base/confirm.vue'; | |
| 41 | + | |
| 42 | + import Mixin from './mixin'; | |
| 43 | + | |
| 44 | + import { initTimeDate, toDate } from '../util'; | |
| 45 | + | |
| 46 | + const prefixCls = 'ivu-picker-panel'; | |
| 47 | + const timePrefixCls = 'ivu-time-picker'; | |
| 48 | + | |
| 49 | + export default { | |
| 50 | + mixins: [Mixin], | |
| 51 | + components: { TimeSpinner, Confirm }, | |
| 52 | + data () { | |
| 53 | + return { | |
| 54 | + prefixCls: prefixCls, | |
| 55 | + timePrefixCls: timePrefixCls, | |
| 56 | + format: 'HH:mm:ss', | |
| 57 | + date: initTimeDate(), | |
| 58 | + dateEnd: initTimeDate(), | |
| 59 | + value: '', | |
| 60 | + hours: '', | |
| 61 | + minutes: '', | |
| 62 | + seconds: '', | |
| 63 | + hoursEnd: '', | |
| 64 | + minutesEnd: '', | |
| 65 | + secondsEnd: '', | |
| 66 | + disabledHours: [], | |
| 67 | + disabledMinutes: [], | |
| 68 | + disabledSeconds: [], | |
| 69 | + hideDisabledOptions: false | |
| 70 | + } | |
| 71 | + }, | |
| 72 | + computed: { | |
| 73 | + classes () { | |
| 74 | + return [ | |
| 75 | + `${prefixCls}-body-wrapper`, | |
| 76 | + `${timePrefixCls}-with-range`, | |
| 77 | + { | |
| 78 | + [`${timePrefixCls}-with-seconds`]: this.showSeconds | |
| 79 | + } | |
| 80 | + ]; | |
| 81 | + }, | |
| 82 | + showSeconds () { | |
| 83 | + return (this.format || '').indexOf('ss') !== -1; | |
| 84 | + } | |
| 85 | + }, | |
| 86 | + watch: { | |
| 87 | + value (newVal) { | |
| 88 | + if (!newVal) { | |
| 89 | + return; | |
| 90 | + } else if (Array.isArray(newVal)) { | |
| 91 | + const valStart = newVal[0] ? toDate(newVal[0]) : false; | |
| 92 | + const valEnd = newVal[1] ? toDate(newVal[1]) : false; | |
| 93 | + | |
| 94 | + if (valStart && valEnd) { | |
| 95 | + this.handleChange( | |
| 96 | + { | |
| 97 | + hours: valStart.getHours(), | |
| 98 | + minutes: valStart.getMinutes(), | |
| 99 | + seconds: valStart.getSeconds() | |
| 100 | + }, | |
| 101 | + { | |
| 102 | + hours: valEnd.getHours(), | |
| 103 | + minutes: valEnd.getMinutes(), | |
| 104 | + seconds: valEnd.getSeconds() | |
| 105 | + }, | |
| 106 | + false | |
| 107 | + ) | |
| 108 | + } | |
| 109 | + } | |
| 110 | + } | |
| 111 | + }, | |
| 112 | + methods: { | |
| 113 | + handleClear() { | |
| 114 | + this.date = initTimeDate(); | |
| 115 | + this.dateEnd = initTimeDate(); | |
| 116 | + this.hours = ''; | |
| 117 | + this.minutes = ''; | |
| 118 | + this.seconds = ''; | |
| 119 | + this.hoursEnd = ''; | |
| 120 | + this.minutesEnd = ''; | |
| 121 | + this.secondsEnd = ''; | |
| 122 | + }, | |
| 123 | + handleChange (date, dateEnd, emit = true) { | |
| 124 | + if (date.hours !== undefined) { | |
| 125 | + this.date.setHours(date.hours); | |
| 126 | + this.hours = this.date.getHours(); | |
| 127 | + } | |
| 128 | + if (date.minutes !== undefined) { | |
| 129 | + this.date.setMinutes(date.minutes); | |
| 130 | + this.minutes = this.date.getMinutes(); | |
| 131 | + } | |
| 132 | + if (date.seconds !== undefined) { | |
| 133 | + this.date.setSeconds(date.seconds); | |
| 134 | + this.seconds = this.date.getSeconds(); | |
| 135 | + } | |
| 136 | + if (dateEnd.hours !== undefined) { | |
| 137 | + this.dateEnd.setHours(dateEnd.hours); | |
| 138 | + this.hoursEnd = this.dateEnd.getHours(); | |
| 139 | + } | |
| 140 | + if (dateEnd.minutes !== undefined) { | |
| 141 | + this.dateEnd.setMinutes(dateEnd.minutes); | |
| 142 | + this.minutesEnd = this.dateEnd.getMinutes(); | |
| 143 | + } | |
| 144 | + if (dateEnd.seconds !== undefined) { | |
| 145 | + this.dateEnd.setSeconds(dateEnd.seconds); | |
| 146 | + this.secondsEnd = this.dateEnd.getSeconds(); | |
| 147 | + } | |
| 148 | + if (emit) this.$emit('on-pick', [this.date, this.dateEnd], true); | |
| 149 | + }, | |
| 150 | + handleStartChange (date) { | |
| 151 | + this.handleChange(date, {}); | |
| 152 | + }, | |
| 153 | + handleEndChange (date) { | |
| 154 | + this.handleChange({}, date); | |
| 155 | + } | |
| 156 | + } | |
| 157 | + }; | |
| 158 | +</script> | |
| 0 | 159 | \ No newline at end of file | ... | ... |
src/components/date-picker/picker.vue
| ... | ... | @@ -201,7 +201,7 @@ |
| 201 | 201 | }, |
| 202 | 202 | iconType () { |
| 203 | 203 | let icon = 'ios-calendar-outline'; |
| 204 | - if (this.type === 'time') icon = 'ios-clock-outline'; | |
| 204 | + if (this.type === 'time' || this.type === 'timerange') icon = 'ios-clock-outline'; | |
| 205 | 205 | if (this.showClose) icon = 'ios-close'; |
| 206 | 206 | return icon; |
| 207 | 207 | }, |
| ... | ... | @@ -408,14 +408,16 @@ |
| 408 | 408 | this.picker.resetView && this.picker.resetView(); |
| 409 | 409 | }, |
| 410 | 410 | emitChange (date) { |
| 411 | - const format = this.format || DEFAULT_FORMATS[this.type]; | |
| 411 | + const type = this.type; | |
| 412 | + const format = this.format || DEFAULT_FORMATS[type]; | |
| 412 | 413 | const formatter = ( |
| 413 | - TYPE_VALUE_RESOLVER_MAP[this.type] || | |
| 414 | + TYPE_VALUE_RESOLVER_MAP[type] || | |
| 414 | 415 | TYPE_VALUE_RESOLVER_MAP['default'] |
| 415 | 416 | ).formatter; |
| 416 | 417 | |
| 417 | 418 | let newDate = formatter(date, format); |
| 418 | - if (this.type === 'daterange') { | |
| 419 | + if (type === 'daterange' || type === 'timerange') { | |
| 420 | + console.log(newDate); | |
| 419 | 421 | newDate = [newDate.split(RANGE_SEPARATOR)[0], newDate.split(RANGE_SEPARATOR)[1]]; |
| 420 | 422 | } |
| 421 | 423 | |
| ... | ... | @@ -443,12 +445,12 @@ |
| 443 | 445 | immediate: true, |
| 444 | 446 | handler (val) { |
| 445 | 447 | const type = this.type; |
| 446 | - if (type === 'time') { | |
| 448 | + if (type === 'time' || type === 'timerange') { | |
| 447 | 449 | const parser = ( |
| 448 | 450 | TYPE_VALUE_RESOLVER_MAP[type] || |
| 449 | 451 | TYPE_VALUE_RESOLVER_MAP['default'] |
| 450 | 452 | ).parser; |
| 451 | - | |
| 453 | + if (type === 'timerange') val = val.join(RANGE_SEPARATOR); | |
| 452 | 454 | val = parser(val, this.format || DEFAULT_FORMATS[type]); |
| 453 | 455 | } |
| 454 | 456 | this.internalValue = val; | ... | ... |
src/components/date-picker/picker/time-picker.js
| 1 | 1 | import Picker from '../picker.vue'; |
| 2 | 2 | import TimePanel from '../panel/time.vue'; |
| 3 | +import TimeRangePanel from '../panel/time-range.vue'; | |
| 3 | 4 | import Options from '../time-mixins'; |
| 4 | 5 | |
| 6 | +const getPanel = function (type) { | |
| 7 | + if (type === 'timerange') { | |
| 8 | + return TimeRangePanel; | |
| 9 | + } | |
| 10 | + return TimePanel; | |
| 11 | +}; | |
| 12 | + | |
| 13 | +import { oneOf } from '../../../utils/assist'; | |
| 14 | + | |
| 5 | 15 | export default { |
| 6 | 16 | mixins: [Picker, Options], |
| 7 | 17 | props: { |
| 18 | + type: { | |
| 19 | + validator (value) { | |
| 20 | + return oneOf(value, ['time', 'timerange']); | |
| 21 | + }, | |
| 22 | + default: 'time' | |
| 23 | + }, | |
| 8 | 24 | value: {} |
| 9 | 25 | }, |
| 10 | - data () { | |
| 11 | - return { | |
| 12 | - type: 'time' | |
| 13 | - }; | |
| 14 | - }, | |
| 15 | 26 | created () { |
| 16 | - this.panel = TimePanel; | |
| 27 | + if (!this.value) { | |
| 28 | + if (this.type === 'timerange') { | |
| 29 | + this.value = ['','']; | |
| 30 | + } else { | |
| 31 | + this.value = ''; | |
| 32 | + } | |
| 33 | + } | |
| 34 | + this.panel = getPanel(this.type); | |
| 17 | 35 | } |
| 18 | 36 | }; |
| 19 | 37 | \ No newline at end of file | ... | ... |
src/styles/components/time-picker.less
| 1 | 1 | @time-picker-prefix-cls: ~"@{css-prefix}time-picker"; |
| 2 | +@time-picker-cells-width: 112px; | |
| 3 | +@time-picker-cells-width-with-seconds: @time-picker-cells-width + 56px; | |
| 4 | + | |
| 2 | 5 | .@{time-picker-prefix-cls} { |
| 3 | 6 | &-cells{ |
| 4 | - min-width: 112px; | |
| 7 | + min-width: @time-picker-cells-width; | |
| 5 | 8 | &-with-seconds{ |
| 6 | - min-width: 168px; | |
| 9 | + min-width: @time-picker-cells-width-with-seconds; | |
| 7 | 10 | } |
| 8 | 11 | |
| 9 | 12 | &-list{ |
| ... | ... | @@ -61,4 +64,59 @@ |
| 61 | 64 | } |
| 62 | 65 | } |
| 63 | 66 | } |
| 67 | + | |
| 68 | + &-header{ | |
| 69 | + height: 32px; | |
| 70 | + line-height: 32px; | |
| 71 | + text-align: center; | |
| 72 | + border-bottom: 1px solid @border-color-split; | |
| 73 | + } | |
| 74 | + | |
| 75 | + &-with-range{ | |
| 76 | + .@{picker-prefix-cls}-panel{ | |
| 77 | + &-body{ | |
| 78 | + min-width: @time-picker-cells-width * 2 + 4px; | |
| 79 | + } | |
| 80 | + &-content{ | |
| 81 | + float: left; | |
| 82 | + position: relative; | |
| 83 | + | |
| 84 | + &:after{ | |
| 85 | + content: ''; | |
| 86 | + display: block; | |
| 87 | + width: 2px; | |
| 88 | + position: absolute; | |
| 89 | + top: 31px; | |
| 90 | + bottom: 0; | |
| 91 | + right: -2px; | |
| 92 | + background: @border-color-split | |
| 93 | + } | |
| 94 | + | |
| 95 | + &-right{ | |
| 96 | + float: right; | |
| 97 | + &:after{ | |
| 98 | + right: auto; | |
| 99 | + left: -2px; | |
| 100 | + } | |
| 101 | + } | |
| 102 | + } | |
| 103 | + } | |
| 104 | + .@{time-picker-prefix-cls}-cells{ | |
| 105 | + &-list{ | |
| 106 | + &:first-child{ | |
| 107 | + border-radius: 0; | |
| 108 | + } | |
| 109 | + &:last-child{ | |
| 110 | + border-radius: 0; | |
| 111 | + } | |
| 112 | + } | |
| 113 | + } | |
| 114 | + } | |
| 115 | + &-with-range&-with-seconds{ | |
| 116 | + .@{picker-prefix-cls}-panel{ | |
| 117 | + &-body{ | |
| 118 | + min-width: @time-picker-cells-width-with-seconds * 2 + 4px; | |
| 119 | + } | |
| 120 | + } | |
| 121 | + } | |
| 64 | 122 | } |
| 65 | 123 | \ No newline at end of file | ... | ... |
test/routers/date.vue
| ... | ... | @@ -6,19 +6,29 @@ |
| 6 | 6 | <template> |
| 7 | 7 | <row> |
| 8 | 8 | <i-col span="12"> |
| 9 | - <date-picker type="date" placeholder="选择日期" style="width: 200px" @on-ok="ok" confirm @on-clear="clear"></date-picker> | |
| 9 | + <!--<date-picker type="date" placeholder="选择日期" style="width: 200px" @on-ok="ok" confirm @on-clear="clear"></date-picker>--> | |
| 10 | 10 | </i-col> |
| 11 | 11 | <i-col span="12"> |
| 12 | - <date-picker type="daterange" placement="bottom-end" placeholder="选择日期" style="width: 200px"></date-picker> | |
| 12 | + <date-picker :value="value3" type="daterange" placement="bottom-start" placeholder="选择日期" style="width: 200px"></date-picker> | |
| 13 | 13 | </i-col> |
| 14 | 14 | <i-col span="12"> |
| 15 | - <span>123,{{value}},456</span> | |
| 16 | 15 | <time-picker |
| 17 | 16 | :value="value" |
| 18 | 17 | placeholder="选择时间" |
| 19 | 18 | format="HH:mm:ss" |
| 20 | 19 | :hide-disabled-options="false" |
| 21 | - :disabled-hours="[1,2,5,10,11]" | |
| 20 | + :disabled-hours="[1,2,10,11]" | |
| 21 | + @on-change="c" | |
| 22 | + @on-ok="ok" | |
| 23 | + @on-clear="clear" | |
| 24 | + style="width: 168px"></time-picker> | |
| 25 | + </i-col> | |
| 26 | + <i-col span="12"> | |
| 27 | + <time-picker | |
| 28 | + :value="value2" | |
| 29 | + type="timerange" | |
| 30 | + placeholder="选择时间" | |
| 31 | + :hide-disabled-options="false" | |
| 22 | 32 | @on-change="c" |
| 23 | 33 | @on-ok="ok" |
| 24 | 34 | @on-clear="clear" |
| ... | ... | @@ -31,7 +41,10 @@ |
| 31 | 41 | data () { |
| 32 | 42 | return { |
| 33 | 43 | // value: '2016-12-12 03:03:03' |
| 34 | - value: '15:12:01' | |
| 44 | + value: '15:12:01', | |
| 45 | + value2: ['08:40:00', '09:40:00'], | |
| 46 | +// value2: [new Date(), new Date()], | |
| 47 | + value3: ['2016-12-01', '2016-12-25'] | |
| 35 | 48 | } |
| 36 | 49 | }, |
| 37 | 50 | methods: { | ... | ... |