• 自定义微信小程序的星星评分组件


    设计需求如下,根据使用功能块的不同,有三种大小的评分设计。

     由于需求中的设计样式与功能基本一致,只是在不同显示区域的大小有些区别。还有就是一些功能上的,如:多事件监听,只读。

    那么完全可以把上述的不同作为properties传入自定义组件,来实现不同的需求功能。

    那么就先配置好自定义组件的相关文件,首先我们可定义一个文件夹custom-star,包含文件有star.wxml, star.js, star.json, star.wxss。

    第一步在star.json中我们需要这么配置:

    {
      "component": true,
      "usingComponent": ""
    }

    将 component字段设为 true 可将这一组文件设为自定义组件。而 usingComponent 这一字段是作为引用组件的页面的json的声明配置项,其值为引用的组件路径。

    然后我们在star.wxml中编写组件的基本机构和需要绑定的属性,值和事件:

    <view class="star_wrapper star_wrapper_{{starSize}}">
      <view wx:for="{{star}}" wx:key="{{item.id}}" data-index="{{item.id}}" data-gradable="{{gradable}}" bindtap="grade">
        <image src="{{item.id > score ? defaultSrc : activeSrc}}"></image>
      </view>
    </view>

    starSize 我们作为定义组件显示的样式属性,通过properties来获取,默认值为normal。对应的还有small, large。这个对应相关的wxss来显示相应的效果、

    star 为数据对象、

    gradable 为当前组件是否可评分(非只读)、

    grade 即为点击事件、

    通过点击事件来改变score值,而来改变image点亮状态。

    对应的star.wxss:

    view{box-sizing: border-box;}
    /* 注意组件的宽度,默认横向撑开整个容器 */
    .star_wrapper{
      display: flex;
      flex: row;
      justify-content: space-between;
      width: 100%;
      height: auto;
    }
    .star_wrapper_normal image{
      width: 38rpx;
      height: 36rpx;
    }
    .star_wrapper_large image{
      width: 52rpx;
      height: 50rpx;
    }
    .star_wrapper_small image{
      width: 30rpx;
      height: 28rpx;
    }

    star.js:

    Component({
      properties: {
        /**
        * 组件大小
        * small: 小
        * normal: 正常
        * large: 大
        */ 
        starSize: {
          type: String,
          value: 'normal'
        },
        // 评分值
        score: {
          type: Number,
          value: 0
        },
        // 同时使用多个组件,事件监听的方法名
        starIdx: {
          type: String,
          value: 'I'
        },
        // 是否可评分
        gradable: {
          type: Boolean,
          value: true
        }
      },
      data: {
        star: [
          {id: 1},
          {id: 2},
          {id: 3},
          {id: 4},
          {id: 5}
        ],
        defaultSrc: '/image/star.png',
        activeSrc: '/image/star_active.png'
      },
      // 组件生命周期
      lifetimes: {
        attached () {
    
        },
        detached () {
    
        }
      },
      // 兼容v2.2.3以下写法
      attached () {
    
      },
      // 挂载页面的生命周期
      pageLifetimes: {
    
      },
      methods: {
        grade (e) {
          // 如果只是展示分值,就屏蔽评分
          if (!this.data.gradable) return;
          this.setData({
            score: e.currentTarget.dataset.index
          }, () => {
            const scoreDetail = {
              score: e.currentTarget.dataset.index
            };
            let evenName = 'getscore' + this.data.starIdx;
            this.triggerEvent(evenName, scoreDetail)
          })
        }
      }
    })

    js中我还定义了一个starIdx, 这里我的思路是如果一个页面有多个star组件被引用了。需要在该页面监听不同的子组件事件,用这个字段来作区别。

    下面我们就可以在其他常规页面中去引用这个组件了。首先在.json文件中,先声明一下:

    {
      "usingComponents": {
        "star": "/custom-star/star"
      }
    }

    然后就直接引用了。注意传值和事件的定义:

    <view class="container">
      <star bind:getscoreI="getscoreI" starSize="{{stars[0].starSize}}" score="{{stars[0].score}}" starIdx="{{stars[0].starIdx}}" gradable="{{stars[0].gradable}}"></star>
      <star bind:getscoreII="getscoreII" starSize="{{stars[1].starSize}}" score="{{stars[1].score}}" starIdx="{{stars[1].starIdx}}"></star>
      <star bind:getscoreIII="getscoreIII" starSize="{{stars[2].starSize}}" score="{{stars[2].score}}" starIdx="{{stars[2].starIdx}}"></star>
    </view>

    自定义事件 bind:getscoreI、bind:getscoreII、bind:getscoreIII。与组件中的 triggerEvent 对应,是我们在本页面需要监听的对应事件。


    需要说一下的是,在读官方文档时,他是这么介绍模板数据绑定的:

    然后我在使用时傻傻的在每个属性值前面都加了前缀 “prop-”,这么根本就拿不到值。;);)


    那么在引用页面中,就只需要传一些对应的数据和定义一些对应事件了。 stars:渲染的数据数组对象,getscoreI...这几个事件。

    Page({
      /**
       * 页面的初始数据
       */
      data: {
        stars: [
          {
            starSize: 'large',
            score: 5,
            starIdx: 'I',
            gradable: false
          },
          {
            starSize: 'normal',
            score: 1,
            starIdx: 'II'
          },
          {
            starSize: 'small',
            score: 4,
            starIdx: 'III'
          }
        ]
      },
      getscoreII(e) {
        console.log(e)
      },
      getscoreIII(e) {
        console.log(e)
      }
    })

    说明:stars 中第一个数据对象中的gradable为false,即这个渲染结果是只读的,不可点击。所以 getscoreI 事件就不用定义了。

    以上是在工作中的小小尝试和总结,如果有错误的地方或者是更优质的编写方法,欢迎指正分享。

  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/matthewkuo24/p/10715962.html
Copyright © 2020-2023  润新知