1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 微信小程序-星星评分组件(支持半星/自定义尺寸)

微信小程序-星星评分组件(支持半星/自定义尺寸)

时间:2020-01-20 01:35:37

相关推荐

微信小程序-星星评分组件(支持半星/自定义尺寸)

由于从网上直接copy的评分组件虽然能用,但是我找到的组件渲染做得稍差,于是准备自己改进一下。

先放一个效果图:

一.准备

准备类似的四张图片,图片一定要根据像素点精准对半切开,否则在小程序中会出现重叠现象。

推荐在iconfont图标库中选择自己想要的图标,下载到本地后使用【画图3D】将图片进行对半裁剪。

示例图片如下:

二. 组件部分

代码的wxss部分借鉴了借鉴文章,但改进了其JS渲染部分。

【说明】:本组件默认评分为1分,最低分为0.5分,不支持打0分。大家可自行更改JS文件stars数组中的flag1和flag2以及star_num来自定义起评分。

在微信开发者工具中新建一个component,此次示例取名为star

1.star.js

【bgImgL】对应未选中左半星图片路径

【bgfImgL】对应已选中左半星图片路径

【bgImgR】对应未选中右半星图片路径

【bgfImgR】对应已选中右半星图片路径

以上四个图片路径请自行替换为本地图片路径

// components/star.jsComponent({/*** 组件的属性列表*/properties: {//接收自定义的高度setSize:Number,},data: {stars: [{flag1: 2,flag2: 2,bgImgL: "/src/icons/Lstar.png",bgfImgL: "/src/icons/Lstar.active.png",bgImgR: "/src/icons/Rstar.png",bgfImgR: "/src/icons/Rstar.active.png",},{flag1: 1,flag2: 1,bgImgL: "/src/icons/Lstar.png",bgfImgL: "/src/icons/Lstar.active.png",bgImgR: "/src/icons/Rstar.png",bgfImgR: "/src/icons/Rstar.active.png",},{flag1: 1,flag2: 1,bgImgL: "/src/icons/Lstar.png",bgfImgL: "/src/icons/Lstar.active.png",bgImgR: "/src/icons/Rstar.png",bgfImgR: "/src/icons/Rstar.active.png",},{flag1: 1,flag2: 1,bgImgL: "/src/icons/Lstar.png",bgfImgL: "/src/icons/Lstar.active.png",bgImgR: "/src/icons/Rstar.png",bgfImgR: "/src/icons/Rstar.active.png",},{flag1:1,flag2:1,bgImgL: "/src/icons/Lstar.png",bgfImgL: "/src/icons/Lstar.active.png",bgImgR: "/src/icons/Rstar.png",bgfImgR: "/src/icons/Rstar.active.png",},],star_num: 1, // 默认1分 最低0.5分Lindex:0, //左下标Rindex:0, //右下标 oldScore:'', //旧分数newScore:''//新分数},/*** 组件的方法列表*/methods: {//点击左边scoreL: function (e) {var _this = this;this.setData({oldScore:this.data.star_num})// console.log("旧分数",this.data.oldScore)var index = e.currentTarget.dataset.index;//改变分数_this.setData({star_num: index + 0.5 // 评分})this.setData({newScore:this.data.star_num})// console.log("新分数",this.data.newScore)this.judgeNum() //重新渲染星星},//点击右边scoreR: function (e) {this.setData({oldScore:this.data.star_num})var _this = this;var index = e.currentTarget.dataset.index;// 评分_this.setData({star_num: index + 1 // 评分})this.setData({newScore:this.data.star_num})this.judgeNum()},changeL(param){//左移 1代表减 2代表加var that = this;// console.log("LL左下标",that.data.Lindex)// console.log("LL右下标",that.data.Rindex)var item ='stars['+that.data.Lindex+'].flag1'if(param===1){ //左移动// console.log("锚点1")const middle = that.data.Lindex var item ='stars['+middle+'].flag1'that.setData({[item]:1,Lindex:that.data.Lindex-1})}if(param===2){// console.log("锚点2")const middle = that.data.Lindex + 1var item ='stars['+middle+'].flag1'that.setData({[item]:2,Lindex:that.data.Lindex+1})}},changeR(param){ //右移 1代表减 2代表加const that = thisvar item ='stars['+that.data.Lindex+'].flag2'if(param===1){ //左移动// console.log("锚点3")that.setData({[item]:1,Rindex:this.data.Rindex-1})}if(param===2){// console.log("锚点4")const middle = that.data.Rindex + 1var item ='stars['+middle+'].flag2'that.setData({[item]:2,Rindex:this.data.Rindex+1})}},judgeNum:function(){const isPoint = (this.data.oldScore) % 1 ==0? false:trueconst flag = this.data.newScore - this.data.oldScore //分差if(flag<0) {//分差小于0 扣分if(isPoint) { //是小数(左)const LorR={toL:true,toR:false,}const count = Math.abs(flag)*2 //变化的次数 LRLRfor (var i=0;i<count;i++){if(LorR.toL){this.changeL(1)}if(LorR.toR){this.changeR(1)}LorR.toL=!LorR.toLLorR.toR=!LorR.toR}}//是整数(右)else{const LorR={toL:false,toR:true,}const count = Math.abs(flag)*2 //变化的次数 LRLRfor (var i=0;i<count;i++){if(LorR.toL){this.changeL(1)}if(LorR.toR){this.changeR(1)}LorR.toL=!LorR.toLLorR.toR=!LorR.toR}}} //分差大于0 加分else{if(isPoint) {//是小数const LorR={toL:false,toR:true,}const count = Math.abs(flag)*2 //变化的次数 LRLRfor (var i=0;i<count;i++){if(LorR.toL){this.changeL(2)}if(LorR.toR){this.changeR(2)}LorR.toL=!LorR.toLLorR.toR=!LorR.toR}}else{ //是整数const LorR={toL:true,toR:false,}const count = Math.abs(flag)*2 //变化的次数 LRLRfor (var i=0;i<count;i++){if(LorR.toL){this.changeL(2)}if(LorR.toR){this.changeR(2)}LorR.toL=!LorR.toLLorR.toR=!LorR.toR}}}},setNum(){ //向父组件传值//传入的参数名称 starNum this.triggerEvent('myevent',{starNum:this.data.star_num})}}})

2.star.wxml

<view class="stars" bindtap="setNum"><view wx:for="{{stars}}" wx:key="index" class="starItem" style="--width--:{{setSize}}rpx;--height--:{{setSize}}rpx"><image src="{{item.flag1 == 1 ? item.bgImgL : item.bgfImgL}}" data-index="{{index}}" bindtap='scoreL'></image><image src="{{item.flag2 == 1 ? item.bgImgR : item.bgfImgR}}" data-index="{{index}}" bindtap='scoreR'></image></view></view>

3.star.wxss

.stars {display: flex;width: var(--width--);height: var(--height--);/* width: 100%;height: 100px; */}.stars view {position: relative;width: var(--width--);height: var(--height--);margin-right: 20rpx;}.stars view image:nth-of-type(1) {width: 50%;height: 100%;margin-right: -2rpx;}.stars view image:nth-of-type(2) {width: 50%;height: 100%;margin-left: -1rpx;}

三.在页面中引用

该组件支持自定义高度,所以在其他页面中引用该组件时,需要传入一个参数来设置其宽高,尺寸为rpx,传入的参数名称为【setSize】,并且该组件支持将每次点击的评分回传到引入该组件的页面。

1.引入页面的json文件

组件的位置请自行替换为自己组件的位置,该处只为示例代码

{"usingComponents": {"star":"../../../components/star/star"}}

2.引入页面的wxml文件

//setSize=100 表示将组件的高度设置为100rpx //bind:myevent =“setStarNum”用于接收子组件回传的评分数值//需在JS文件中写一个【setStarNum】函数<star setSize='100' bind:myevent="setStarNum"></star>

3.引入页面的js文件

setStarNum(e){console.log("获得的评分为",e.detail.starNum)},//评分已经拿到了,如何处理及操作可自行编写

四.效果演示

经过优化后的渲染过程不会出现原来copy的代码中星星频闪的问题,实际变化过程中要流畅很多,放两种图片自行对比

1.已优化

2.未优化

在切换时可看到明显的频闪现象。有兴趣的具体有可以去看借鉴的原文章,频闪是因为其每次都将原来星星的状态清零且重新渲染时未按顺序填色导致的。

编写不易,若使用过程中出现bug欢迎交流指正。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。