一、微信小程序——评分
index.wxml
<view>
<image
wx:for="{{stars}}"
wx:key="id"
src="{{item.src}}"
data-clickIndex="{{item.id}}"
bindtap="rating"
style="width:48rpx;height:48rpx;vertical-align: middle;" /> {{starNum}}分
</view>
index.js
//星星的图片路径
var starOffImg = "/images/com_icon/star_off.png";
var starOnImg = "/images/com_icon/star_on.png";
Page({
/**
* 页面的初始数据
*/
data: {
starNum: 0,//分数
stars: [//星星数组
{
id:1,
src: starOffImg,
active: false
}, {
id:2,
src: starOffImg,
active: false
}, {
id:3,
src: starOffImg,
active: false
},
{
id:4,
src: starOffImg,
active: false
}, {
id:5,
src: starOffImg,
active: false
}
],
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
rating(e){
var total = this.data.stars.length; //星星总数
var idx = e.currentTarget.dataset.clickindex //这代表选的第idx颗星-也代表应该显示的星星数量
// console.log(e.currentTarget.dataset.clickindex)//点击的星星的id
if (this.data.starNum == 0) { //进入if说明页面为初始状态
this.setData({
starNum:idx
})
for(var i = 0; i < idx; i++){
var srcChange='stars['+i+'].src'
var activeChange='stars['+i+'].active'
this.setData({
[srcChange]:starOnImg,
[activeChange]:true
})
}
// console.log(this.data.stars)
} else {
//如果再次点击当前选中的星级-仅取消掉当前星级,保留之前的。
if (idx == this.data.starNum) {
for (var i = idx-1; i < total; i++) {
var srcChange='stars['+i+'].src'
var activeChange='stars['+i+'].active'
this.setData({
[srcChange]:starOffImg,
[activeChange]:false
})
}
}
//如果小于当前最高星级,则直接保留当前星级
if (idx < this.data.starNum) {
for (var i = idx; i < this.data.starNum; i++) {
var srcChange='stars['+i+'].src'
var activeChange='stars['+i+'].active'
this.setData({
[srcChange]:starOffImg,
[activeChange]:false
})
}
}
//如果大于当前星级,则直接选到该星级
if (idx > this.data.starNum) {
for (var i = 0; i < idx; i++) {
var srcChange='stars['+i+'].src'
var activeChange='stars['+i+'].active'
this.setData({
[srcChange]:starOnImg,
[activeChange]:true
})
}
}
var count = 0; //计数器-统计当前有几颗星
for (var i = 0; i < total; i++) {
if (this.data.stars[i].active) {
count++;
}
}
//得到总评分,赋值给starNum
this.setData({
starNum:count
})
}
}
})
重点:小程序与Vue赋值不同,赋值得拼接,之后用[ ]
包起来
for(var i = 0; i < idx; i++){
var srcChange='stars['+i+'].src'
var activeChange='stars['+i+'].active'
this.setData({
[srcChange]:starOnImg,
[activeChange]:true
})
}
评分:
二、微信小程序——显示评分组件
score.wxml
<view class="star-List">
<block wx:for="{{starsList}}" wx:forItem="item" wx:key="*this">
<image class="star-item" src="{{item}}"></image>
</block>
</view>
score.js
// components/score/score.js
Component({
/**
* 组件的属性列表
*/
properties: {
score: Number
},
/**
* 组件的初始数据
*/
data: {
},
lifetimes: {
// 生命周期函数,可以为函数,或一个在methods段中定义的方法名
attached: function () {
this.getStarClass()
}
},
observers: {//使用数据监听器
'score': function(score) {
// 在 rate被设置时,执行这个函数
this.getStarClass()
}
},
methods: {
getStarClass(){//处理score
let result = [];
let score = Math.floor(this.data.score * 2) / 2;
let hasDecimal = score % 1 !== 0;
let integer = Math.floor(score); //返回小于等于x的最大整数:
for (let i = 0; i < integer; i++) {
result.push("../../images/com_icon/star_on.png");
}
if (hasDecimal) {
result.push("../../images/com_icon/star_half.png");//半星
}
while (result.length < 5) {
result.push("../../images/com_icon/star_off.png");
}
this.setData({
starsList:result
})
}
}
})
这里有个坑:发现从后台获取数据后赋值给score,发现组件还是没有更新,直接就赋了默认的值0,对数据打印后,发现是生命周期出现了问题,因为网络原因,数据还没有出来,子组件的 attached 生命周期已加载,所以赋了默认的值。
解决方法:在Component 中使用数据监听器 observers
observers: {//使用数据监听器
'score': function(score) {
// 在 score 被设置时,执行这个函数
this.getStarClass() //
}
}
参考:https://blog.csdn.net/qq_40190624/article/details/89792136
score.wxss
.star-item {
display: inline-block;
width: 30rpx;
height: 30rpx;
}
.star-List{
display: inline-block;
height: 60rpx;
line-height: 60rpx;
}
--------------------------------------------------------------------使用该组件------------------------------------------------------------------
mine.json
"usingComponents": {
"score":"/components/score/score"
}
mine.html
<score score="{{score}}"></score>
score与组件中的properties要一致
properties: {
score: Number
},
mine.js
Page({
/**
* 页面的初始数据
*/
data: {
score: 4.5,//评分
},
onLoad: function (options) {//生命周期函数--监听页面加载
}
})
显示: