2
2
<view class =" u-rate" :id =" elId" @touchmove.stop.prevent =" touchMove" >
3
3
<view class =" u-star-wrap" v-for =" (item, index) in count" :key =" index" :class =" [elClass]" >
4
4
<u-icon
5
- :name =" activeIndex > index ? activeIcon : inactiveIcon"
5
+ :name =" activeIndex > index ? elActiveIcon : inactiveIcon"
6
6
@click =" click(index + 1, $event)"
7
- :color =" activeIndex > index ? activeColor : inactiveColor"
7
+ :color =" activeIndex > index ? elActiveColor : inactiveColor"
8
8
:custom-style =" {
9
9
fontSize: size + 'rpx',
10
10
padding: `0 ${gutter / 2 + 'rpx'}`
11
11
}"
12
+ :custom-prefix =" customPrefix"
13
+ :show-decimal-icon =" showDecimalIcon(index)"
14
+ :percent =" decimal"
12
15
></u-icon >
13
16
</view >
14
17
</view >
15
18
</template >
16
19
17
- <script >
18
- /**
20
+ <script >/**
19
21
* rate 评分
20
22
* @description 该组件一般用于满意度调查,星型评分的场景
21
23
* @tutorial https://www.uviewui.com/components/rate.html
29
31
* @property {String} inactive -icon 未选中时的图标名,只能为uView的内置图标(默认star)
30
32
* @property {String} gutter 星星之间的距离(默认10)
31
33
* @property {String Number} min -count 最少选中星星的个数(默认0)
34
+ * @property {Array} colors 颜色分级显示,可以用不同颜色区分评分层级
35
+ * @property {Array} icons 图标分级显示,可以用不同类型的icon区分评分层级
32
36
* @property {Boolean} allow -half 是否允许半星选择(默认false)
33
37
* @event {Function} change 选中的星星发生变化时触发
34
38
* @example < u- rate : count= " count" : current= " 2" >< / u- rate>
35
39
*/
40
+
36
41
export default {
37
42
name: ' u-rate' ,
38
43
props: {
@@ -97,6 +102,25 @@ export default {
97
102
inactiveIcon: {
98
103
type: String ,
99
104
default: ' star'
105
+ },
106
+ // 自定义扩展前缀,方便用户扩展自己的图标库
107
+ customPrefix: {
108
+ type: String ,
109
+ default: ' uicon'
110
+ },
111
+ // 颜色分级显示,可以用不同颜色区分评分层级
112
+ colors: {
113
+ type: Array ,
114
+ default () {
115
+ return []
116
+ }
117
+ },
118
+ // 图标分级显示,可以用不同类型的icon区分评分层级
119
+ icons: {
120
+ type: Array ,
121
+ default () {
122
+ return []
123
+ }
100
124
}
101
125
},
102
126
data () {
@@ -109,94 +133,125 @@ export default {
109
133
activeIndex: this .value != - 1 ? this .value : this .current ,
110
134
starWidth: 0 , // 每个星星的宽度
111
135
starWidthArr: [] // 每个星星最右边到组件盒子最左边的距离
112
- };
136
+ }
113
137
},
114
138
watch: {
115
139
current (val ) {
116
- this .activeIndex = val;
140
+ this .activeIndex = val
117
141
},
118
142
value (val ) {
119
- this .activeIndex = val;
143
+ this .activeIndex = val
144
+ }
145
+ },
146
+ computed: {
147
+ decimal () {
148
+ if (this .disabled ) {
149
+ return this .activeIndex * 100 % 100
150
+ } else if (this .allowHalf ) {
151
+ return 50
152
+ }
153
+ },
154
+ elActiveIcon () {
155
+ const len = this .icons .length
156
+ if (len) {
157
+ const step = Math .round (this .activeIndex / Math .round (this .count / len))
158
+ if (step > len) return this .icons [len - 1 ]
159
+ return this .icons [step - 1 ]
160
+ }
161
+ return this .activeIcon
162
+ },
163
+ elActiveColor () {
164
+ const len = this .colors .length
165
+ if (len) {
166
+ const step = Math .round (this .activeIndex / Math .round (this .count / len))
167
+ if (step > len) return this .colors [len - 1 ]
168
+ return this .colors [step - 1 ]
169
+ }
170
+ return this .activeColor
120
171
}
121
172
},
122
173
methods: {
123
174
// 获取评分组件盒子的布局信息
124
175
getElRectById () {
125
176
// uView封装的获取节点的方法,详见文档
126
- this .$uGetRect (' #' + this .elId ).then (res => {
127
- this .starBoxLeft = res .left ;
177
+ this .$u . getRect (' #' + this .elId ).then (res => {
178
+ this .starBoxLeft = res .left
128
179
})
129
180
},
130
181
// 获取单个星星的尺寸
131
182
getElRectByClass () {
132
183
// uView封装的获取节点的方法,详见文档
133
- this .$uGetRect (' .' + this .elClass ).then (res => {
134
- this .starWidth = res .width ;
184
+ this .$u . getRect (' .' + this .elClass ).then (res => {
185
+ this .starWidth = res .width
135
186
// 把每个星星右边到组件盒子左边的距离放入数组中
136
187
for (let i = 0 ; i < this .count ; i++ ) {
137
- this .starWidthArr [i] = (i + 1 ) * this .starWidth ;
188
+ this .starWidthArr [i] = (i + 1 ) * this .starWidth
138
189
}
139
190
})
140
191
},
141
192
// 手指滑动
142
193
touchMove (e ) {
143
194
if (this .disabled ) {
144
- return ;
195
+ return
145
196
}
146
197
if (! e .changedTouches [0 ]) {
147
- return ;
198
+ return
148
199
}
149
- const movePageX = e .changedTouches [0 ].pageX ;
200
+ const movePageX = e .changedTouches [0 ].pageX
150
201
// 滑动点相对于评分盒子左边的距离
151
- const distance = movePageX - this .starBoxLeft ;
202
+ const distance = movePageX - this .starBoxLeft
152
203
153
204
// 如果滑动到了评分盒子的左边界,就设置为0星
154
205
if (distance <= 0 ) {
155
- this .activeIndex = 0 ;
206
+ this .activeIndex = 0
156
207
}
157
208
// 滑动的距离,相当于多少颗星星
158
- let index = Math .ceil (distance / this .starWidth );
159
- this .activeIndex = index > this .count ? this .count : index;
209
+ let index = Math .ceil (distance / this .starWidth )
210
+ this .activeIndex = index > this .count ? this .count : index
160
211
// 对最少颗星星的限制
161
- if (this .activeIndex < this .minCount ) this .activeIndex = this .minCount ;
162
- this .emitEvent ();
212
+ if (this .activeIndex < this .minCount ) this .activeIndex = this .minCount
213
+ this .emitEvent ()
163
214
},
164
215
// 通过点击,直接选中
165
216
click (index , e ) {
166
217
if (this .disabled ) {
167
- return ;
218
+ return
168
219
}
169
220
// 半星选择,尚未实现
170
221
if (this .allowHalf ) {
171
222
}
172
223
// 对第一个星星特殊处理,只有一个的时候,点击可以取消,否则无法作0星评价
173
224
if (index == 1 ) {
174
- if (this .activeIndex == 1 ) this .activeIndex = 0 ;
175
- else this .activeIndex = 1 ;
225
+ if (this .activeIndex == 1 ) {
226
+ this .activeIndex = 0
227
+ } else {
228
+ this .activeIndex = 1
229
+ }
176
230
} else {
177
- this .activeIndex = index;
231
+ this .activeIndex = index
178
232
}
179
233
// 对最少颗星星的限制
180
- if (this .activeIndex < this .minCount ) this .activeIndex = this .minCount ;
181
- this .emitEvent ();
234
+ if (this .activeIndex < this .minCount ) this .activeIndex = this .minCount
235
+ this .emitEvent ()
182
236
},
183
237
// 发出事件
184
238
emitEvent () {
185
239
// 发出change事件
186
- this .$emit (' change' , this .activeIndex );
240
+ this .$emit (' change' , this .activeIndex )
187
241
// 同时修改双向绑定的value的值
188
- if (this .value != - 1 ) {
189
- this .$emit (' input' , this .activeIndex );
242
+ if (this .value != - 1 ) {
243
+ this .$emit (' input' , this .activeIndex )
190
244
}
245
+ },
246
+ showDecimalIcon (index ) {
247
+ return this .disabled && parseInt (this .activeIndex ) === index
191
248
}
192
249
},
193
250
mounted () {
194
- setTimeout (() => {
195
- this .getElRectById ();
196
- this .getElRectByClass ();
197
- }, 100 )
251
+ this .getElRectById ()
252
+ this .getElRectByClass ()
198
253
}
199
- };
254
+ }
200
255
</script >
201
256
202
257
<style scoped lang="scss">
0 commit comments