Commit 49d380cf99f3ce6e144b6b0626b32ec8bd2f476b
1 parent
1ff55186
init Rate component
init Rate component
Showing
9 changed files
with
193 additions
and
1 deletions
Show diff stats
| 1 | +<template> | |
| 2 | + <div :class="classes" @mouseleave="handleMouseleave"> | |
| 3 | + <div v-for="item in count" :class="starCls(item)"> | |
| 4 | + <span | |
| 5 | + :class="[prefixCls + '-star-content']" | |
| 6 | + @mousemove="handleMousemove(item, $event)" | |
| 7 | + @click="handleClick(item)"></span> | |
| 8 | + </div> | |
| 9 | + </div> | |
| 10 | +</template> | |
| 11 | +<script> | |
| 12 | + const prefixCls = 'ivu-rate'; | |
| 13 | + | |
| 14 | + export default { | |
| 15 | + props: { | |
| 16 | + count: { | |
| 17 | + type: Number, | |
| 18 | + default: 5 | |
| 19 | + }, | |
| 20 | + value: { | |
| 21 | + type: Number, | |
| 22 | + default: 0 | |
| 23 | + }, | |
| 24 | + allowHalf: { | |
| 25 | + type: Boolean, | |
| 26 | + default: false | |
| 27 | + }, | |
| 28 | + disabled: { | |
| 29 | + type: Boolean, | |
| 30 | + default: false | |
| 31 | + } | |
| 32 | + }, | |
| 33 | + data () { | |
| 34 | + return { | |
| 35 | + prefixCls: prefixCls, | |
| 36 | + hoverIndex: -1 | |
| 37 | + }; | |
| 38 | + }, | |
| 39 | + computed: { | |
| 40 | + classes () { | |
| 41 | + return [ | |
| 42 | + `${prefixCls}`, | |
| 43 | + { | |
| 44 | + [`${prefixCls}-disabled`]: this.disabled | |
| 45 | + } | |
| 46 | + ] | |
| 47 | + } | |
| 48 | + }, | |
| 49 | + methods: { | |
| 50 | + starCls (value) { | |
| 51 | + const hoverIndex = this.hoverIndex; | |
| 52 | + let full = false; | |
| 53 | + | |
| 54 | + if (hoverIndex >= value) { | |
| 55 | + full = true; | |
| 56 | + } | |
| 57 | + | |
| 58 | + return [ | |
| 59 | + `${prefixCls}-star`, | |
| 60 | + { | |
| 61 | + [`${prefixCls}-star-full`]: full, | |
| 62 | + [`${prefixCls}-star-zero`]: !full | |
| 63 | + } | |
| 64 | + ] | |
| 65 | + }, | |
| 66 | + handleMousemove(value, event) { | |
| 67 | + if (this.disabled) return; | |
| 68 | + | |
| 69 | + if (this.allowHalf) { | |
| 70 | +// let target = event.target; | |
| 71 | +// if (hasClass(target, 'el-rate__item')) { | |
| 72 | +// target = target.querySelector('.el-rate__icon'); | |
| 73 | +// } | |
| 74 | +// if (hasClass(target, 'el-rate__decimal')) { | |
| 75 | +// target = target.parentNode; | |
| 76 | +// } | |
| 77 | +// this.pointerAtLeftHalf = event.offsetX * 2 <= target.clientWidth; | |
| 78 | +// this.currentValue = this.pointerAtLeftHalf ? value - 0.5 : value; | |
| 79 | + } else { | |
| 80 | + this.currentValue = value; | |
| 81 | + } | |
| 82 | + this.hoverIndex = value; | |
| 83 | + }, | |
| 84 | + handleMouseleave () { | |
| 85 | + if (this.disabled) { | |
| 86 | + return; | |
| 87 | + } | |
| 88 | + if (this.allowHalf) { | |
| 89 | +// this.pointerAtLeftHalf = this.value !== Math.floor(this.value); | |
| 90 | + } | |
| 91 | +// this.currentValue = this.value; | |
| 92 | + this.hoverIndex = -1; | |
| 93 | + }, | |
| 94 | + handleClick (value) { | |
| 95 | + | |
| 96 | + } | |
| 97 | + } | |
| 98 | + }; | |
| 99 | +</script> | |
| 0 | 100 | \ No newline at end of file | ... | ... |
src/index.js
| ... | ... | @@ -27,6 +27,7 @@ import Page from './components/page'; |
| 27 | 27 | import Poptip from './components/poptip'; |
| 28 | 28 | import Progress from './components/progress'; |
| 29 | 29 | import Radio from './components/radio'; |
| 30 | +import Rate from './components/rate'; | |
| 30 | 31 | import Slider from './components/slider'; |
| 31 | 32 | import Spin from './components/spin'; |
| 32 | 33 | import Steps from './components/steps'; |
| ... | ... | @@ -83,6 +84,7 @@ const iview = { |
| 83 | 84 | Progress, |
| 84 | 85 | Radio, |
| 85 | 86 | RadioGroup: Radio.Group, |
| 87 | + Rate, | |
| 86 | 88 | Row, |
| 87 | 89 | iSelect: Select, |
| 88 | 90 | Slider, | ... | ... |
src/styles/components/index.less
| 1 | +@rate-prefix-cls: ~"@{css-prefix}rate"; | |
| 2 | + | |
| 3 | +.@{rate-prefix-cls} { | |
| 4 | + display: inline-block; | |
| 5 | + margin: 0; | |
| 6 | + padding: 0; | |
| 7 | + font-size: 20px; | |
| 8 | + vertical-align: middle; | |
| 9 | + font-weight: normal; | |
| 10 | + font-style: normal; | |
| 11 | + font-family: 'Ionicons'; | |
| 12 | + | |
| 13 | + &-disabled &-star { | |
| 14 | + &:before, | |
| 15 | + &-content:before { | |
| 16 | + cursor: default; | |
| 17 | + } | |
| 18 | + &:hover { | |
| 19 | + transform: scale(1); | |
| 20 | + } | |
| 21 | + } | |
| 22 | + | |
| 23 | + &-star { | |
| 24 | + display: inline-block; | |
| 25 | + margin: 0; | |
| 26 | + padding: 0; | |
| 27 | + margin-right: 8px; | |
| 28 | + position: relative; | |
| 29 | + transition: all 0.3s ease; | |
| 30 | + | |
| 31 | + &:hover { | |
| 32 | + transform: scale(1.1); | |
| 33 | + } | |
| 34 | + | |
| 35 | + &:before, | |
| 36 | + &-content:before { | |
| 37 | + color: #e9e9e9; | |
| 38 | + cursor: pointer; | |
| 39 | + content: "\F4B3"; | |
| 40 | + transition: all @transition-time @ease-in-out; | |
| 41 | + display: block; | |
| 42 | + } | |
| 43 | + | |
| 44 | + &-content { | |
| 45 | + position: absolute; | |
| 46 | + left: 0; | |
| 47 | + top: 0; | |
| 48 | + width: 50%; | |
| 49 | + height: 100%; | |
| 50 | + overflow: hidden; | |
| 51 | + &:before { | |
| 52 | + color: transparent; | |
| 53 | + } | |
| 54 | + } | |
| 55 | + | |
| 56 | + &-half &-content:before, | |
| 57 | + &-full:before { | |
| 58 | + color: @rate-star-color; | |
| 59 | + } | |
| 60 | + | |
| 61 | + &-half:hover &-content:before, | |
| 62 | + &-full:hover:before { | |
| 63 | + color: tint(@rate-star-color, 20%); | |
| 64 | + } | |
| 65 | + } | |
| 66 | +} | |
| 0 | 67 | \ No newline at end of file | ... | ... |
src/styles/themes/default/custom.less
test/app.vue
test/main.js
| ... | ... | @@ -134,6 +134,11 @@ router.map({ |
| 134 | 134 | require(['./routers/form.vue'], resolve); |
| 135 | 135 | } |
| 136 | 136 | }, |
| 137 | + '/rate': { | |
| 138 | + component: function (resolve) { | |
| 139 | + require(['./routers/rate.vue'], resolve); | |
| 140 | + } | |
| 141 | + }, | |
| 137 | 142 | }); |
| 138 | 143 | |
| 139 | 144 | router.beforeEach(function () { | ... | ... |