打分评分效果是很常用的功能,比如豆瓣评分里面经常出现的五星评分等,今天就给大家做一个类似的评分效果。
写在前面
在制作一个医院类小程序的前端时,有一个功能是对医院进行评价,通过查找资料并结合自身的知识花了一个下午终于解决了。(由于知识欠缺的原因,中间一个问题阻碍了几个小时,即为下文所陈列问题的第二条)。
效果预览
分别截取了无评分状态和评价状态的页面:
未选中
选中
代码实现
1、feedback.js
-
// pages/more/feedback.js
-
Page({
-
-
/**
-
* 页面的初始数据
-
*/
-
data: {
-
// 评价图片
-
evaluationImgUrl: "https://s1.ax1x.com/2018/08/05/PDM8Bj.png",
-
starCheckedImgUrl: "https://s1.ax1x.com/2018/08/05/PDQ0it.png",
-
starUnCheckedImgUrl: "https://s1.ax1x.com/2018/08/05/PDQdII.png",
-
-
// 建议内容
-
opinion: "",
-
-
starMap: [
-
'非常差',
-
'差',
-
'一般',
-
'好',
-
'非常好',
-
],
-
-
evaluations: [
-
{
-
id: 0,
-
name: "医院环境",
-
image: "https://s1.ax1x.com/2018/08/05/PDMaCV.png",
-
star: 0,
-
note: ""
-
},
-
{
-
id: 1,
-
name: "医生专业技术",
-
image: "https://s1.ax1x.com/2018/08/05/PDMd3T.png",
-
star: 0,
-
note: ""
-
},
-
{
-
id: 2,
-
name: "医生态度",
-
image: "https://s1.ax1x.com/2018/08/05/PDMN40.png",
-
star: 0,
-
note: ""
-
}
-
]
-
},
-
-
/**
-
* 评分
-
*/
-
chooseStar: function (e) {
-
const index = e.currentTarget.dataset.index;
-
const star = e.target.dataset.star;
-
let evaluations = this.data.evaluations;
-
let evaluation = evaluations[index];
-
// console.log(evaluation)
-
evaluation.star = star;
-
evaluation.note = this.data.starMap[star-1];
-
this.setData({
-
evaluations: evaluations
-
})
-
}
-
})
2、feedback.wxml
-
<!--pages/more/feedback.wxml-->
-
<view class='container'>
-
-
<view class='card'>
-
-
<!-- 为方便数据定位,自定义了wx:for-item为i -->
-
<block wx:for='{{evaluations}}' wx:for-item='i' wx:key=''>
-
<view class='card-item'>
-
<view class='item-title'>
-
<view class='image-container title-image'>
-
<image src='{{i.image}}'></image>
-
</view>
-
<view class='title-text'>{{i.name}}</view>
-
</view>
-
<view class='item-content'>
-
<view class='image-container content-image'>
-
<image src='{{evaluationImgUrl}}'></image>
-
</view>
-
<view class='contet-text content-body'>
-
<!-- 为方便数据定位,自定义了wx:for-item为j -->
-
<block wx:for='{{starMap}}' wx:for-item='j' wx:key=''>
-
<view class='image-container' data-index='{{i.id}}' bindtap='chooseStar'>
-
<image wx:if='{{i.star >= index + 1}}' data-star='{{index + 1}}' src='{{starCheckedImgUrl}}' bin></image>
-
<image wx:if='{{i.star < index + 1}}' data-star='{{index + 1}}' src='{{starUnCheckedImgUrl}}'></image>
-
</view>
-
</block>
-
<text class='note'>{{i.note}}</text>
-
</view>
-
</view>
-
</view>
-
</block>
-
-
</view>
-
-
<view class='submit' bindtap='submit'>提交反馈</view>
-
-
</view>
只贴出关键代码,不附样式代码。
问题及解决方案
1、image图片没有点击事件。
给image图片加上一层外部容器,然后在这一层容器加上点击事件。
2、三个评价内容是通过列表渲染实现的,而每个评价内容中的五个星星图片也是通过列表渲染实现的,这样就存在一个嵌套循环。此时,如何清楚地知道到底点了哪一个评价项的第几颗星?
默认的当前元素变量名都是item,这样的话,在里层循环里使用item指向的是里层的数组,而无法找到外层循环里的内容。于是我对两层数组当前元素的变量名进行重命名(分别命名为 i 和 j ),这样在里层使用i.*也可以访问到外层数组的数据项。
3、如何动态显示星级?
在wx:for里面嵌套wx:if或者hidden都可以实现效果。当星星下标+1小于或者等于当前星级的时候,就显示为被选中的星星;当星星下标+1大于当前星级的时候,就显示为被选中的星星。当星星被点中时,就将相应项的星级改为被点击的星星的下标+1。