zoukankan      html  css  js  c++  java
  • 自定义微信小程序的星星评分组件

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

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

    那么完全可以把上述的不同作为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 事件就不用定义了。

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

  • 相关阅读:
    用find和xargs处理文件名中带空格的文件
    python调用Shell
    python 的sys.argv 和 sys.path.append() 用法和PYTHONPATH环境变量
    pytorch中 model.cuda的作用
    Python中变量和对象的关系
    python中的import、from import以及import as的区别
    常用功能bash脚本
    图像数据增强-图像补边
    python中的glob库函数
    喵哈哈村的七十六
  • 原文地址:https://www.cnblogs.com/matthewkuo24/p/10715962.html
Copyright © 2011-2022 走看看