Commit 2d94873892ee673f5eb8a2fa578d3edf8686e536
1 parent
36628aca
update TimePicker & BackTop
update TimePicker & BackTop
Showing
9 changed files
with
179 additions
and
98 deletions
Show diff stats
.eslintrc.json
src/components/back-top/back-top.vue
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | </div> |
9 | 9 | </template> |
10 | 10 | <script> |
11 | + import { scrollTop } from '../../utils/assist'; | |
11 | 12 | const prefixCls = 'ivu-back-top'; |
12 | 13 | |
13 | 14 | export default { |
... | ... | @@ -23,6 +24,10 @@ |
23 | 24 | right: { |
24 | 25 | type: Number, |
25 | 26 | default: 30 |
27 | + }, | |
28 | + duration: { | |
29 | + type: Number, | |
30 | + default: 1000 | |
26 | 31 | } |
27 | 32 | }, |
28 | 33 | data () { |
... | ... | @@ -62,7 +67,7 @@ |
62 | 67 | this.backTop = window.pageYOffset >= this.height; |
63 | 68 | }, |
64 | 69 | back () { |
65 | - window.scrollTo(0, 0); | |
70 | + scrollTop(window, document.body.scrollTop, 0, this.duration); | |
66 | 71 | this.$emit('on-click'); |
67 | 72 | } |
68 | 73 | } | ... | ... |
src/components/date-picker/base/time-spinner.vue
1 | 1 | <template> |
2 | 2 | <div :class="classes"> |
3 | - <div :class="[prefixCls+ '-wrapper']"> | |
4 | - <ul :class="[prefixCls + '-list']"> | |
5 | - <li :class="getCellCls(item)" v-for="item in hoursList" v-show="!item.hide">{{ item.text }}</li> | |
3 | + <div :class="[prefixCls+ '-list']" v-el:hours> | |
4 | + <ul @click="handleClickHours"> | |
5 | + <li :class="getCellCls(item)" v-for="item in hoursList" v-show="!item.hide" :index="$index">{{ item.text < 10 ? '0' + item.text : item.text }}</li> | |
6 | 6 | </ul> |
7 | 7 | </div> |
8 | - <div :class="[prefixCls+ '-wrapper']"> | |
9 | - <ul :class="[prefixCls + '-list']"> | |
10 | - <li :class="getCellCls(item)" v-for="item in minutesList" v-show="!item.hide">{{ item.text }}</li> | |
8 | + <div :class="[prefixCls+ '-list']" v-el:minutes> | |
9 | + <ul @click="handleClickMinutes"> | |
10 | + <li :class="getCellCls(item)" v-for="item in minutesList" v-show="!item.hide" :index="$index">{{ item.text < 10 ? '0' + item.text : item.text }}</li> | |
11 | 11 | </ul> |
12 | 12 | </div> |
13 | - <div :class="[prefixCls+ '-wrapper']" v-show="showSeconds"> | |
14 | - <ul :class="[prefixCls + '-list']"> | |
15 | - <li :class="getCellCls(item)" v-for="item in secondsList" v-show="!item.hide">{{ item.text }}</li> | |
13 | + <div :class="[prefixCls+ '-list']" v-show="showSeconds" v-el:seconds> | |
14 | + <ul @click="handleClickSeconds"> | |
15 | + <li :class="getCellCls(item)" v-for="item in secondsList" v-show="!item.hide" :index="$index">{{ item.text < 10 ? '0' + item.text : item.text }}</li> | |
16 | 16 | </ul> |
17 | 17 | </div> |
18 | 18 | </div> |
19 | 19 | </template> |
20 | 20 | <script> |
21 | 21 | import Options from '../time-mixins'; |
22 | - import { deepCopy } from '../../../utils/assist'; | |
22 | + import { deepCopy, scrollTop } from '../../../utils/assist'; | |
23 | 23 | |
24 | 24 | const prefixCls = 'ivu-time-picker-cells'; |
25 | 25 | |
... | ... | @@ -60,7 +60,7 @@ |
60 | 60 | hoursList () { |
61 | 61 | let hours = []; |
62 | 62 | const hour_tmpl = { |
63 | - text: '', | |
63 | + text: 0, | |
64 | 64 | selected: false, |
65 | 65 | disabled: false, |
66 | 66 | hide: false |
... | ... | @@ -74,6 +74,7 @@ |
74 | 74 | hour.disabled = true; |
75 | 75 | if (this.hideDisabledOptions) hour.hide = true; |
76 | 76 | } |
77 | + if (this.hours === i) hour.selected = true; | |
77 | 78 | hours.push(hour); |
78 | 79 | } |
79 | 80 | |
... | ... | @@ -82,7 +83,7 @@ |
82 | 83 | minutesList () { |
83 | 84 | let minutes = []; |
84 | 85 | const minute_tmpl = { |
85 | - text: '', | |
86 | + text: 0, | |
86 | 87 | selected: false, |
87 | 88 | disabled: false, |
88 | 89 | hide: false |
... | ... | @@ -96,6 +97,7 @@ |
96 | 97 | minute.disabled = true; |
97 | 98 | if (this.hideDisabledOptions) minute.hide = true; |
98 | 99 | } |
100 | + if (this.minutes === i) minute.selected = true; | |
99 | 101 | minutes.push(minute); |
100 | 102 | } |
101 | 103 | |
... | ... | @@ -104,7 +106,7 @@ |
104 | 106 | secondsList () { |
105 | 107 | let seconds = []; |
106 | 108 | const second_tmpl = { |
107 | - text: '', | |
109 | + text: 0, | |
108 | 110 | selected: false, |
109 | 111 | disabled: false, |
110 | 112 | hide: false |
... | ... | @@ -118,6 +120,7 @@ |
118 | 120 | second.disabled = true; |
119 | 121 | if (this.hideDisabledOptions) second.hide = true; |
120 | 122 | } |
123 | + if (this.seconds === i) second.selected = true; | |
121 | 124 | seconds.push(second); |
122 | 125 | } |
123 | 126 | |
... | ... | @@ -133,6 +136,29 @@ |
133 | 136 | [`${prefixCls}-cell-disabled`]: cell.disabled |
134 | 137 | } |
135 | 138 | ]; |
139 | + }, | |
140 | + handleClickHours (event) { | |
141 | + this.handleClick('hours', event); | |
142 | + }, | |
143 | + handleClickMinutes (event) { | |
144 | + this.handleClick('minutes', event); | |
145 | + }, | |
146 | + handleClickSeconds (event) { | |
147 | + this.handleClick('seconds', event); | |
148 | + }, | |
149 | + handleClick (type, event) { | |
150 | + const target = event.target; | |
151 | + if (target.tagName === 'LI') { | |
152 | + const cell = this[`${type}List`][parseInt(event.target.getAttribute('index'))]; | |
153 | + if (cell.disabled) return; | |
154 | + const data = {}; | |
155 | + data[type] = cell.text; | |
156 | + this.$emit('on-change', data); | |
157 | + | |
158 | + const from = this.$els[type].scrollTop; | |
159 | + const to = 24 * cell.text; | |
160 | + scrollTop(this.$els[type], from, to, 500); | |
161 | + } | |
136 | 162 | } |
137 | 163 | } |
138 | 164 | }; | ... | ... |
src/components/date-picker/panel/time.vue
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | minutes: newVal.getMinutes(), |
64 | 64 | seconds: newVal.getSeconds() |
65 | 65 | }); |
66 | - this.$nextTick(() => this.scrollTop()); | |
66 | +// this.$nextTick(() => this.scrollTop()); | |
67 | 67 | } |
68 | 68 | } |
69 | 69 | }, |
... | ... | @@ -81,9 +81,6 @@ |
81 | 81 | this.date.setSeconds(date.seconds); |
82 | 82 | this.seconds = this.date.getSeconds(); |
83 | 83 | } |
84 | - }, | |
85 | - scrollTop () { | |
86 | - | |
87 | 84 | } |
88 | 85 | } |
89 | 86 | }; | ... | ... |
src/styles/components/index.less
1 | +@time-picker-prefix-cls: ~"@{css-prefix}time-picker"; | |
2 | +.@{time-picker-prefix-cls} { | |
3 | + &-cells{ | |
4 | + min-width: 112px; | |
5 | + &-with-seconds{ | |
6 | + min-width: 168px; | |
7 | + } | |
8 | + | |
9 | + &-list{ | |
10 | + width: 56px; | |
11 | + float: left; | |
12 | + position: relative; | |
13 | + max-height: 144px; | |
14 | + overflow-y: auto; | |
15 | + border-left: 1px solid @border-color-split; | |
16 | + &:first-child{ | |
17 | + border-left: none; | |
18 | + border-radius: @btn-border-radius 0 0 0; | |
19 | + } | |
20 | + &:last-child{ | |
21 | + border-radius: 0 @btn-border-radius 0 0; | |
22 | + } | |
23 | + ul{ | |
24 | + width: 100%; | |
25 | + margin: 0; | |
26 | + padding: 0 0 120px 0; | |
27 | + list-style: none; | |
28 | + li{ | |
29 | + width: 100%; | |
30 | + height: 24px; | |
31 | + line-height: 24px; | |
32 | + margin: 0; | |
33 | + padding: 0 0 0 16px; | |
34 | + box-sizing: border-box; | |
35 | + text-align: left; | |
36 | + user-select: none; | |
37 | + cursor: pointer; | |
38 | + list-style: none; | |
39 | + transition: background @transition-time @ease-in-out; | |
40 | + | |
41 | + } | |
42 | + } | |
43 | + } | |
44 | + &-cell{ | |
45 | + &:hover{ | |
46 | + background: @background-color-select-hover; | |
47 | + } | |
48 | + &-disabled { | |
49 | + color: @btn-disable-color; | |
50 | + cursor: @cursor-disabled; | |
51 | + | |
52 | + &:hover { | |
53 | + color: @btn-disable-color; | |
54 | + background-color: #fff; | |
55 | + cursor: @cursor-disabled; | |
56 | + } | |
57 | + } | |
58 | + &-selected ,&-selected:hover{ | |
59 | + color: @primary-color; | |
60 | + background: @background-color-select-hover; | |
61 | + } | |
62 | + } | |
63 | + } | |
64 | +} | |
0 | 65 | \ No newline at end of file | ... | ... |
src/utils/assist.js
... | ... | @@ -86,7 +86,7 @@ function firstUpperCase(str) { |
86 | 86 | export function warnProp(component, prop, correctType, wrongType) { |
87 | 87 | correctType = firstUpperCase(correctType); |
88 | 88 | wrongType = firstUpperCase(wrongType); |
89 | - console.error(`[iView warn]: Invalid prop: type check failed for prop ${prop}. Expected ${correctType}, got ${wrongType}. (found in component: ${component})`); | |
89 | + console.error(`[iView warn]: Invalid prop: type check failed for prop ${prop}. Expected ${correctType}, got ${wrongType}. (found in component: ${component})`); // eslint-disable-line | |
90 | 90 | } |
91 | 91 | |
92 | 92 | function typeOf(obj) { |
... | ... | @@ -131,4 +131,37 @@ function deepCopy(data) { |
131 | 131 | return o; |
132 | 132 | } |
133 | 133 | |
134 | -export {deepCopy}; | |
135 | 134 | \ No newline at end of file |
135 | +export {deepCopy}; | |
136 | + | |
137 | +// scrollTop animation | |
138 | +export function scrollTop(el, from = 0, to, duration = 500) { | |
139 | + if (!window.requestAnimationFrame) { | |
140 | + window.requestAnimationFrame = ( | |
141 | + window.webkitRequestAnimationFrame || | |
142 | + window.mozRequestAnimationFrame || | |
143 | + window.msRequestAnimationFrame || | |
144 | + function (callback) { | |
145 | + return window.setTimeout(callback, 1000/60); | |
146 | + } | |
147 | + ) | |
148 | + } | |
149 | + const difference = Math.abs(from - to); | |
150 | + const step = Math.ceil(difference / duration * 50); | |
151 | + | |
152 | + function scroll(start, end, step) { | |
153 | + if (start === end) return; | |
154 | + | |
155 | + let d = (start + step > end) ? end : start + step; | |
156 | + if (start > end) { | |
157 | + d = (start - step < end) ? end : start - step; | |
158 | + } | |
159 | + | |
160 | + if (el === window) { | |
161 | + window.scrollTo(d, d); | |
162 | + } else { | |
163 | + el.scrollTop = d; | |
164 | + } | |
165 | + window.requestAnimationFrame(() => scroll(d, end, step)); | |
166 | + } | |
167 | + scroll(from, to, step); | |
168 | +} | |
136 | 169 | \ No newline at end of file | ... | ... |
test/routers/date.vue
1 | +<style> | |
2 | + body{ | |
3 | + height: auto !important; | |
4 | + } | |
5 | +</style> | |
1 | 6 | <template> |
2 | 7 | <row> |
3 | 8 | <i-col span="12"> |
... | ... | @@ -7,12 +12,16 @@ |
7 | 12 | <date-picker type="daterange" placement="bottom-end" placeholder="选择日期" style="width: 200px"></date-picker> |
8 | 13 | </i-col> |
9 | 14 | <i-col span="12"> |
10 | - <time-picker placeholder="选择时间" :hide-disabled-options="false" :disabled-hours="[1,2]" style="width: 200px"></time-picker> | |
15 | + <time-picker :value="value" placeholder="选择时间" format="HH:mm:ss" :hide-disabled-options="false" :disabled-hours="[1,2]" style="width: 168px"></time-picker> | |
11 | 16 | </i-col> |
12 | 17 | </row> |
13 | 18 | </template> |
14 | 19 | <script> |
15 | 20 | export default { |
16 | - | |
21 | + data () { | |
22 | + return { | |
23 | + value: '2016-12-12 03:03:03' | |
24 | + } | |
25 | + } | |
17 | 26 | } |
18 | 27 | </script> | ... | ... |
test/routers/more.vue
1 | -<style scoped> | |
2 | - .demo-row{ | |
3 | - margin-bottom: 5px; | |
4 | - background-image: -webkit-linear-gradient(0deg, #F5F5F5 4.16666667%, transparent 4.16666667%, transparent 8.33333333%, #F5F5F5 8.33333333%, #F5F5F5 12.5%, transparent 12.5%, transparent 16.66666667%, #F5F5F5 16.66666667%, #F5F5F5 20.83333333%, transparent 20.83333333%, transparent 25%, #F5F5F5 25%, #F5F5F5 29.16666667%, transparent 29.16666667%, transparent 33.33333333%, #F5F5F5 33.33333333%, #F5F5F5 37.5%, transparent 37.5%, transparent 41.66666667%, #F5F5F5 41.66666667%, #F5F5F5 45.83333333%, transparent 45.83333333%, transparent 50%, #F5F5F5 50%, #F5F5F5 54.16666667%, transparent 54.16666667%, transparent 58.33333333%, #F5F5F5 58.33333333%, #F5F5F5 62.5%, transparent 62.5%, transparent 66.66666667%, #F5F5F5 66.66666667%, #F5F5F5 70.83333333%, transparent 70.83333333%, transparent 75%, #F5F5F5 75%, #F5F5F5 79.16666667%, transparent 79.16666667%, transparent 83.33333333%, #F5F5F5 83.33333333%, #F5F5F5 87.5%, transparent 87.5%, transparent 91.66666667%, #F5F5F5 91.66666667%, #F5F5F5 95.83333333%, transparent 95.83333333%); | |
5 | - background-image: linear-gradient(90deg, #F5F5F5 4.16666667%, transparent 4.16666667%, transparent 8.33333333%, #F5F5F5 8.33333333%, #F5F5F5 12.5%, transparent 12.5%, transparent 16.66666667%, #F5F5F5 16.66666667%, #F5F5F5 20.83333333%, transparent 20.83333333%, transparent 25%, #F5F5F5 25%, #F5F5F5 29.16666667%, transparent 29.16666667%, transparent 33.33333333%, #F5F5F5 33.33333333%, #F5F5F5 37.5%, transparent 37.5%, transparent 41.66666667%, #F5F5F5 41.66666667%, #F5F5F5 45.83333333%, transparent 45.83333333%, transparent 50%, #F5F5F5 50%, #F5F5F5 54.16666667%, transparent 54.16666667%, transparent 58.33333333%, #F5F5F5 58.33333333%, #F5F5F5 62.5%, transparent 62.5%, transparent 66.66666667%, #F5F5F5 66.66666667%, #F5F5F5 70.83333333%, transparent 70.83333333%, transparent 75%, #F5F5F5 75%, #F5F5F5 79.16666667%, transparent 79.16666667%, transparent 83.33333333%, #F5F5F5 83.33333333%, #F5F5F5 87.5%, transparent 87.5%, transparent 91.66666667%, #F5F5F5 91.66666667%, #F5F5F5 95.83333333%, transparent 95.83333333%); | |
6 | - } | |
7 | - .demo-col{ | |
8 | - color: #fff; | |
9 | - padding: 30px 0; | |
10 | - text-align: center; | |
11 | - font-size: 18px; | |
12 | - background: rgba(0, 153, 229, .7); | |
13 | - } | |
14 | - .demo-col.light{ | |
15 | - background: rgba(0, 153, 229, .5); | |
16 | - } | |
17 | - .demo-row.light .demo-col{ | |
18 | - background: rgba(0, 153, 229, .5); | |
19 | - } | |
20 | - .demo-row.light .demo-col.light{ | |
21 | - background: rgba(0, 153, 229, .3); | |
22 | - } | |
23 | - | |
24 | - .ivu-col, .ivu-col div{ | |
25 | - color: #fff; | |
26 | - padding: 10px 0; | |
27 | - text-align: center; | |
28 | - background: rgba(0, 153, 229, .9); | |
29 | - } | |
30 | - .gutter .ivu-col{ | |
31 | - background: transparent !important; | |
32 | - } | |
33 | - .ivu-col:nth-child(odd), .ivu-col:nth-child(odd) div{ | |
34 | - background: rgba(0, 153, 229, .7); | |
35 | - } | |
36 | - | |
37 | - .code-row-bg{ | |
38 | - background: rgba(0,0,0,.05); | |
1 | +<style> | |
2 | + body{ | |
3 | + height: 2000px !important; | |
39 | 4 | } |
40 | 5 | </style> |
41 | 6 | <template> |
42 | - <p>子元素向左排列</p> | |
43 | - <Row type="flex" justify="start" class="code-row-bg"> | |
44 | - <i-col span="4">col-4</i-col> | |
45 | - <i-col span="4">col-4</i-col> | |
46 | - <i-col span="4">col-4</i-col> | |
47 | - <i-col span="4">col-4</i-col> | |
48 | - </Row> | |
49 | - <p>子元素向右排列</p> | |
50 | - <Row type="flex" justify="end" class="code-row-bg"> | |
51 | - <i-col span="4">col-4</i-col> | |
52 | - <i-col span="4">col-4</i-col> | |
53 | - <i-col span="4">col-4</i-col> | |
54 | - <i-col span="4">col-4</i-col> | |
55 | - </Row> | |
56 | - <p>子元素居中排列</p> | |
57 | - <Row type="flex" justify="center" class="code-row-bg"> | |
58 | - <i-col span="4">col-4</i-col> | |
59 | - <i-col span="4">col-4</i-col> | |
60 | - <i-col span="4">col-4</i-col> | |
61 | - <i-col span="4">col-4</i-col> | |
62 | - </Row> | |
63 | - <p>子元素等宽排列</p> | |
64 | - <Row type="flex" justify="space-between" class="code-row-bg"> | |
65 | - <i-col span="4">col-4</i-col> | |
66 | - <i-col span="4">col-4</i-col> | |
67 | - <i-col span="4">col-4</i-col> | |
68 | - <i-col span="4">col-4</i-col> | |
69 | - </Row> | |
70 | - <p>子元素分散排列</p> | |
71 | - <Row type="flex" justify="space-around" class="code-row-bg"> | |
72 | - <i-col span="4">col-4</i-col> | |
73 | - <i-col span="4">col-4</i-col> | |
74 | - <i-col span="4">col-4</i-col> | |
75 | - <i-col span="4">col-4</i-col> | |
76 | - </Row> | |
7 | + {{properties|json}}<br> | |
8 | + {{units|json}} | |
9 | + <Checkbox-group :model.sync="properties"> | |
10 | + <Checkbox v-for="unit in units" :value="unit.UnitName"></Checkbox> | |
11 | + </Checkbox-group> | |
12 | + <Back-top></Back-top> | |
77 | 13 | </template> |
78 | 14 | <script> |
79 | 15 | export default { |
80 | - | |
16 | + data () { | |
17 | + return { | |
18 | + properties: [], | |
19 | + units: [] | |
20 | + } | |
21 | + }, | |
22 | + ready () { | |
23 | + setTimeout(() => { | |
24 | + this.units = [{UnitName:"件"},{UnitName:"箱"},{UnitName:"双"}]; | |
25 | + }, 1000); | |
26 | + } | |
81 | 27 | } |
82 | 28 | </script> | ... | ... |