zoukankan      html  css  js  c++  java
  • WeChat-SmallProgram:自定义select下拉选项框组件

    1):创建组件所需的文件

    2):自定义组件 CSS 及 JS

    组件的wxml:

    <view class='com-selectBox'>
        <view class='com-sContent' bindtap='selectToggle'>
            <view class='com-sTxt'>{{nowText}}</view>
            <image src='../../public/img/local/down.png'  class='com-sImg'  animation="{{animationData}}"></image>
        </view>
        <view class='com-sList' wx:if="{{selectShow}}">
            <view wx:for="{{propArray}}" data-index="{{index}}" wx:key='' class='com-sItem' bindtap='setText'>{{item.text}}</view>
        </view>
    </view>

    1): animation="{{animationData}}" 这个是下箭头的动画效果

    2): data-index="{{index}}" 这个是当前元素被点击时的索引

    3):selectToggle是模仿下拉选项框隐藏和显示的事件。

    4):setText是模仿下拉选项框选择子项之后,设置内容的事件。

    5):selectShow是表示option选项显示与否

    组件的wxss:

    .com-selectBox{
         200px;
    }
    .com-sContent{
        border: 1px solid #e2e2e2;
        background: white;
        font-size: 16px;
        position: relative;
        height: 30px;
        line-height: 30px;
    }
    .com-sImg{
        position: absolute;
        right: 10px;
        top: 11px;
         16px;
        height: 9px;
        transition: all .3s ease;
    }
    .com-sTxt{
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        padding:0 20px 0 6px;
        font-size: 14px;
    }
    .com-sList{
        background: white;
         inherit;
        position: absolute;
        border: 1px solid #e2e2e2;
        border-top: none;
        box-sizing: border-box;
        z-index: 3;
        max-height: 120px;
        overflow: auto;
    }
    .com-sItem{
        height: 30px;
        line-height: 30px;
        border-top: 1px solid #e2e2e2;
        padding: 0 6px;
        text-align: left;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 14px;
    }
    .com-sItem:first-child{
        border-top: none;
    }

    组件的 js:

    // components/select.js
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
        propArray: {
          type: Array,
        }
      },
    
      /**
       * 组件的初始数据
       */
      data: {
        selectShow: false, //初始option不显示
        nowText: "请选择分类", //初始内容
        animationData: {} //右边箭头的动画
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
        //option的显示与否
        selectToggle: function() {
          console.log("select-selectToggle");
          var nowShow = this.data.selectShow; //获取当前option显示的状态
          //创建动画
          var animation = wx.createAnimation({
            timingFunction: "ease"
          })
          this.animation = animation;
          if (nowShow) {
            animation.rotate(0).step();
            this.setData({
              animationData: animation.export()
            })
          } else {
            animation.rotate(180).step();
            this.setData({
              animationData: animation.export()
            });
          }
          this.setData({
            selectShow: !nowShow
          })
        },
        //设置内容
        setText: function(e) {
          console.log("select-setText");
          var nowData = this.properties.propArray; //当前option的数据是引入组件的页面传过来的,所以这里获取数据只有通过this.properties
          var index = e.target.dataset.index; //当前点击的索引
          var nowId = nowData[index].id;
          var nowText = nowData[index].text; //当前点击的内容
          //再次执行动画,注意这里一定,一定,一定是this.animation来使用动画
          this.animation.rotate(0).step();
          this.setData({
            selectShow: false,
            nowText: nowText,
            animationData: this.animation.export()
          });
          var nowDate = {
            id: nowId,
            text: nowText
          }
          this.triggerEvent('myget', nowDate)
        },
        // 初始化数据
        initData(e) {
          console.log("select-initData");
          this.setData({
            selectShow: false, //初始option不显示
            nowText: "请选择分类", //初始内容
            animationData: {} //右边箭头的动画
          });
        }
      }
    })

    1):组件的 properties 属性是对外属性,我理解的是可以当做 data 数据来使用,它是一个含有三个属性的对象,分别是 type 表示属性类型、 value 表示属性初始值、 observer 表示属性值被更改时的响应函数。

      type 是必填的,其它的可选。

      如果只有 type,可以写成:属性名:type类型

    2):组件的 data 和普通页面的data一样,是组件的内部数据,和 properties 一同用于组件的模版渲染。

    3):组件的 method 是专门用于 事件响应函数 和 任意的自定义方法。在这里面获取数据有两种方法:

      一种是获取data里的数据: this.data.属性名

      一种是获取 properties 中的属性值: this.properties.属性名

    4):创建animation动画,作用在通过 true 和 false 切换显示状态的内容上没有过渡、没有过渡、没有过渡

     

    引入组件,传入组件所需数据:

    1. 引入前,需要在引入组件的页面的json文件中配置,比如我要在 index.wxml 中引入,那么在 index.json 中我就需要配置:

    1):sub-unit-select 是你定义的组件的名称,后面的是组件所在的位置。 /  单斜杠表示根目录,是绝对路径。

    2):如果出现下面这种说没找到路径的,一定是自己填写的路径不对,认真查找。

    配置好后,就可以引入组件:

     <sub-unit-select id="init" prop-array='{{selectArray}}' bind:myget='getDataSelect'></sub-unit-select>

    1):prop-array 是我自定义的属性名,这个是和组件所在的 js 中properties中的属性是对应的。

      在 properties 定义的属性中,属性名采用驼峰写法(例如:propArray);在引入组件的 wxml 中,指定属性值时则对应使用连字符写法(例如:prop-array="...")。

    2):id="init" 也是自定义的属性  用来获取组件信息。例如我们要在引用页面 调用 组件内的方法。

     onLoad: function(options) {
        console.log("album-details-onload");
    
        // 获取引用组件信息
        this.compData = this.selectComponent("#init")
    
      },
      // 自定义事件
     modalCancel(e) {
        console.log("album-details-modalCancel");
        var _this = this;
        this.compData.initData();
    
      },

    3):bind:myget='getDataSelect' 获取点击的内容,即组件间的通信。效果有了,最关键的是获取选中的内容。这个怎么实现呢,这时候需要 组建间通信与事件 了。

      这里myget是自定义的子组件需要触发的事件名,getDataSelect 是引入组件的页面需要获取传过来的数据的自定义的事件名。

      子组件触发事件:

      因为这里的select组件是点击下拉列表的内容才进行内容的更新,所以这里只需要在下拉列表里添加一个点击事件,而原来已经设置了setText事件。

      所以只需要在setText函数里面写触发事件就行了。

     var nowDate = {
            id: nowId,
            text: nowText
        }
    this.triggerEvent('myget', nowDate)

    这里的 myget 和 bind:myget ,名称一定要对应。

    nowDate是需要传回的数据,不一定要弄成对象,想传什么传什么,我这里只是演示而已。我试了一下也可以传函数。。。

    最后就是传入数据了。在引入组件的js的data中,添加:

    selectArray: [{
        "id": "10",
        "text": "会计类"
    }, {
        "id": "21",
        "text": "工程类"
    }]

    最终结果:

    如果引入两个相同的组件,传入的数据也相同: 

    <sub-unit-select id="init" prop-array='{{selectArray}}' bind:myget='事件名称2'></sub-unit-select>
    <sub-unit-select id="init" prop-array='{{selectArray}}' bind:myget='事件名称2'></sub-unit-select>

    这样的方式组件并不会相互影响,都是独立的。   

    对了,组件样式的规则可以查看 官方的规则

    在引用组件的页面 JS 中添加函数 :

    // 获取下拉框选择的数据
      getDataSelect: function(e) {
        console.log("album-details-getDataSelect");
        var _this = this;
        console.log(e)
      },

    e 的内容:

     传过来的值就在detail里面。

    到此,一个完整的select组件就完成了。

     

     

    You have to work hard to look effortless

    You're going to sneak up and surprise everyone

     

     

    引文:https://www.cnblogs.com/zjjDaily/p/9548433.htm

  • 相关阅读:
    使用comet架构实现了一个基于网页的视频监控prototype!!!!哇哈哈庆祝一下
    Pixysoft.Framework.Noebe.Datamining 数据挖掘开发实录
    论创业成功!让大家的青春充满着无限美好的回忆
    新年第一篇 数据库备份恢复系统上线的挫折
    .Net FrameWork 4.0中使用EF向数据库插入数据报datatime2类型错误的解决办法
    RoRoWoBlog 开源博客系统介绍
    第一次偶然出现的“System.Data.Entity.dll”类型的异常
    序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    我也来说说Entity Frame Work 4中的数据库优先和代码优先两种方式(2)
    Asp.net MVC 2 + Castle + NHibernate 项目实战(1)
  • 原文地址:https://www.cnblogs.com/codingmode/p/12546704.html
Copyright © 2011-2022 走看看