[微信小程序] 自定义评分组件

一、微信小程序——评分

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) {//生命周期函数--监听页面加载 
  } 

})

显示:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值