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 | \ No newline at end of file | 100 | \ No newline at end of file |
src/index.js
@@ -27,6 +27,7 @@ import Page from './components/page'; | @@ -27,6 +27,7 @@ import Page from './components/page'; | ||
27 | import Poptip from './components/poptip'; | 27 | import Poptip from './components/poptip'; |
28 | import Progress from './components/progress'; | 28 | import Progress from './components/progress'; |
29 | import Radio from './components/radio'; | 29 | import Radio from './components/radio'; |
30 | +import Rate from './components/rate'; | ||
30 | import Slider from './components/slider'; | 31 | import Slider from './components/slider'; |
31 | import Spin from './components/spin'; | 32 | import Spin from './components/spin'; |
32 | import Steps from './components/steps'; | 33 | import Steps from './components/steps'; |
@@ -83,6 +84,7 @@ const iview = { | @@ -83,6 +84,7 @@ const iview = { | ||
83 | Progress, | 84 | Progress, |
84 | Radio, | 85 | Radio, |
85 | RadioGroup: Radio.Group, | 86 | RadioGroup: Radio.Group, |
87 | + Rate, | ||
86 | Row, | 88 | Row, |
87 | iSelect: Select, | 89 | iSelect: Select, |
88 | Slider, | 90 | Slider, |
src/styles/components/index.less
@@ -34,4 +34,5 @@ | @@ -34,4 +34,5 @@ | ||
34 | @import "menu"; | 34 | @import "menu"; |
35 | @import "date-picker"; | 35 | @import "date-picker"; |
36 | @import "time-picker"; | 36 | @import "time-picker"; |
37 | -@import "form"; | ||
38 | \ No newline at end of file | 37 | \ No newline at end of file |
38 | +@import "form"; | ||
39 | +@import "rate"; | ||
39 | \ No newline at end of file | 40 | \ No newline at end of file |
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 | \ No newline at end of file | 67 | \ No newline at end of file |
src/styles/themes/default/custom.less
@@ -14,6 +14,7 @@ | @@ -14,6 +14,7 @@ | ||
14 | @selected-color : fade(@primary-color, 90%); | 14 | @selected-color : fade(@primary-color, 90%); |
15 | @tooltip-color : #fff; | 15 | @tooltip-color : #fff; |
16 | @subsidiary-color : #9ea7b4; | 16 | @subsidiary-color : #9ea7b4; |
17 | +@rate-star-color : #f5a623; | ||
17 | 18 | ||
18 | // Base | 19 | // Base |
19 | @body-background : #fff; | 20 | @body-background : #fff; |
test/app.vue
@@ -47,6 +47,7 @@ li + li { | @@ -47,6 +47,7 @@ li + li { | ||
47 | <li><a v-link="'/menu'">Menu</a></li> | 47 | <li><a v-link="'/menu'">Menu</a></li> |
48 | <li><a v-link="'/date'">Date</a></li> | 48 | <li><a v-link="'/date'">Date</a></li> |
49 | <li><a v-link="'/form'">Form</a></li> | 49 | <li><a v-link="'/form'">Form</a></li> |
50 | + <li><a v-link="'/rate'">Rate</a></li> | ||
50 | </ul> | 51 | </ul> |
51 | </nav> | 52 | </nav> |
52 | <router-view></router-view> | 53 | <router-view></router-view> |
test/main.js
@@ -134,6 +134,11 @@ router.map({ | @@ -134,6 +134,11 @@ router.map({ | ||
134 | require(['./routers/form.vue'], resolve); | 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 | router.beforeEach(function () { | 144 | router.beforeEach(function () { |