Commit 962c40bd3df53df30f73785beea0509c2e8d0362
1 parent
d94d98c4
update Rate
update Rate
Showing
2 changed files
with
57 additions
and
32 deletions
Show diff stats
src/components/rate/rate.vue
1 | 1 | <template> |
2 | 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> | |
3 | + <div | |
4 | + v-for="item in count" | |
5 | + :class="starCls(item)" | |
6 | + @mousemove="handleMousemove(item, $event)" | |
7 | + @click="handleClick(item)"> | |
8 | + <span :class="[prefixCls + '-star-content']" type="half"></span> | |
8 | 9 | </div> |
9 | 10 | </div> |
10 | 11 | </template> |
... | ... | @@ -33,7 +34,9 @@ |
33 | 34 | data () { |
34 | 35 | return { |
35 | 36 | prefixCls: prefixCls, |
36 | - hoverIndex: -1 | |
37 | + hoverIndex: -1, | |
38 | + isHover: false, | |
39 | + isHalf: false | |
37 | 40 | }; |
38 | 41 | }, |
39 | 42 | computed: { |
... | ... | @@ -46,53 +49,68 @@ |
46 | 49 | ]; |
47 | 50 | } |
48 | 51 | }, |
52 | + watch: { | |
53 | + value: { | |
54 | + immediate: true, | |
55 | + handler (val) { | |
56 | + this.setHalf(val); | |
57 | + } | |
58 | + } | |
59 | + }, | |
49 | 60 | methods: { |
50 | 61 | starCls (value) { |
51 | 62 | const hoverIndex = this.hoverIndex; |
63 | + const currentIndex = this.isHover ? hoverIndex : this.value; | |
64 | + | |
52 | 65 | let full = false; |
66 | + let isLast = false; | |
67 | + | |
68 | + if (currentIndex > value) full = true; | |
53 | 69 | |
54 | - if (hoverIndex >= value) { | |
55 | - full = true; | |
70 | + if (this.isHover) { | |
71 | + isLast = currentIndex === value + 1; | |
72 | + } else { | |
73 | + isLast = Math.ceil(this.value) === value + 1; | |
56 | 74 | } |
57 | 75 | |
58 | 76 | return [ |
59 | 77 | `${prefixCls}-star`, |
60 | 78 | { |
61 | - [`${prefixCls}-star-full`]: full, | |
79 | + [`${prefixCls}-star-full`]: (!isLast && full) || (isLast && !this.isHalf), | |
80 | + [`${prefixCls}-star-half`]: isLast && this.isHalf, | |
62 | 81 | [`${prefixCls}-star-zero`]: !full |
63 | 82 | } |
64 | 83 | ]; |
65 | 84 | }, |
66 | - handleMousemove(value) { | |
85 | + handleMousemove(value, event) { | |
67 | 86 | if (this.disabled) return; |
68 | 87 | |
88 | + this.isHover = true; | |
69 | 89 | 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; | |
90 | + const type = event.target.getAttribute('type') || false; | |
91 | + this.isHalf = type === 'half'; | |
79 | 92 | } else { |
80 | - this.currentValue = value; | |
93 | + this.isHalf = false; | |
81 | 94 | } |
82 | - this.hoverIndex = value; | |
95 | + this.hoverIndex = value + 1; | |
83 | 96 | }, |
84 | 97 | 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; | |
98 | + if (this.disabled) return; | |
99 | + | |
100 | + this.isHover = false; | |
101 | + this.setHalf(this.value); | |
92 | 102 | this.hoverIndex = -1; |
93 | 103 | }, |
94 | - handleClick () { | |
95 | - | |
104 | + setHalf (val) { | |
105 | + this.isHalf = val.toString().indexOf('.') >= 0; | |
106 | + }, | |
107 | + handleClick (value) { | |
108 | + if (this.disabled) return; | |
109 | + value++; | |
110 | + if (this.isHalf) value -= 0.5; | |
111 | + this.value = value; | |
112 | + this.$emit('on-change', value); | |
113 | + this.$dispatch('on-form-change', value); | |
96 | 114 | } |
97 | 115 | } |
98 | 116 | }; | ... | ... |
test/routers/rate.vue
1 | 1 | <template> |
2 | 2 | <div style="margin: 100px"> |
3 | - <Rate></Rate> | |
3 | + {{value}} | |
4 | + <br><br><br> | |
5 | + <Rate :value.sync="value" :count="5" allow-half></Rate> | |
6 | + <br><br><br> | |
7 | + <i-button @click="value++">add</i-button> | |
8 | + <i-button @click="value--">remove</i-button> | |
4 | 9 | </div> |
5 | 10 | </template> |
6 | 11 | <script> |
7 | 12 | export default { |
8 | 13 | props: {}, |
9 | 14 | data () { |
10 | - return {}; | |
15 | + return { | |
16 | + value: 3.8 | |
17 | + }; | |
11 | 18 | }, |
12 | 19 | computed: {}, |
13 | 20 | methods: {} | ... | ... |