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