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: { | ... | ... |