美文网首页
【小程序】自定义组件之component

【小程序】自定义组件之component

作者: 嘻洋洋 | 来源:发表于2019-01-19 17:15 被阅读0次

    1.自定义组件用做什么?

    • 可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用。
    • 也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。

    2.应用场景

    • 底部的Tab栏,顶部的标题栏
    • 在不同的页面中,有时候会用到相同的功能模块,此时我们就可以将这些相同的部分提取出来并且单独设为一个"页面",然后在要应用到它的地方引用就可以了。

    3.具体应用

    3.1组件定义需要做的重点工作。

    页面部分要素:属性(properties)、方法、slot(插入的内容)

    <!-- 这是自定义组件的内部WXML结构 -->
    <view class="inner">
      {{innerText}}
      <button bindtap='customMethod'>点击</button>
      <slot></slot>
    </view>
    
    • wxml的slot
      一个组件的wxml中只能有一个slot。需要使用多slot时,可以在组件js中声明启用。
    <!--
      页面框架
      1. 首部
      2. 主体内容
      3. 底部导航
    -->
    <import src="../../plugin/confirm/confirm.wxml" />
    <view class="container" style="padding-bottom:{{paddingBottom}}; {{style}}">
      <!--<image src="{{loggifsrc}}" style="display:none"></image>-->
      <slot name="header"></slot>
      <slot name="body"></slot>
      <slot name="bottom"></slot>
      <!--  已经到底了 -->
      <block wx:if="{{showDeadline}}">
        <view class="usermotto" style="{{deadLineStyle}}">
            <!-- <text class="user-motto line" decode='true'>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;</text> -->
            <text class="user-motto text" > 哇哦,已经到最后咯~</text>
            <!-- <text class="user-motto line" decode='true' >&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;</text> -->
        </view>
      </block>
      <!--  滚动到顶部 -->
      <block wx:if="{{toTop}}">
        <view class="back-top" bindtap="scrolltop">
          <image src="https://image.hh.com/wechat/wxmp/order/arrow.png"></image>
          <text>顶部</text>
        </view>
      </block>
      <!-- 页面弹窗模板 -->
        <template is="confirmbox"  wx:if="{{showComfirmBox}}"data="{{confirmBox:confirmBox}}"/>
    </view>
    
    • 组件的对外属性
      properties:组件的对外属性,结合data属性一同用于组件的模版渲染。都是用于渲染,区别在于组件的属性存放公共数据的地方,可以供调用方传递数据,而data是私有属性的地方,data中的数据只有组件可以访问,外部无法访问
      如何定义属性:属性设置中可包含三个字段, type 表示属性类型、 value 表示属性初始值、 observer 表示属性值被更改时的响应函数
      properties: {
        myProperty: { // 属性名
          type: String, // 类型,目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
          value: '', // 属性初始值(可选),如果未指定则会根据类型选择一个
          observer: function(newVal, oldVal, changedPath) {
             // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange'
             // 通常 newVal 就是新设置的数据, oldVal 是旧数据
          }
        },
        myProperty2: String // 简化的定义方式
      },
    

    当然了也可以简化:

    //--------调用页面-------
      data () {
        return {
          //短信验证码
          info: {
            sms_gb: 50
          }
      }
      <!--短信验证码弹框-->
      <verificode id="verificode" info="{{info}}" bind:onSmsValid="onSmsValid" bind:onCloseSms="onCloseSms" wx:if="{{isShowSmsSend}}"></verificode> 
      </view>
    //-------------组件页面---------------
      //info属性
      properties () {
        return {
          info: Object
        }
      }
    

    使用 this.data 可以获取内部数据和属性值,但不要直接修改它们,应使用 setData 修改

    let { rtnCode, rtnMsg, validateCode } = await that.API.sendSms(phone, this.data.info.sms_gb)
    

    **注意:属性名应避免以 data 开头,即不要命名成 dataXyz 这样的形式,因为在 WXML 中, data-xyz="" 会被作为节点 dataset 来处理,而不是组件属性**

    • 组件的方法
      组件的方法,包括事件响应函数和任意的自定义方法都必须写在methods方法里面。
    //组件里面页面元素的事件。比如说button、view元素绑定的事件。
    <view class="btn-group">
         <view class="btn-cancle" bindtap="onBindCancel">取消</view>
        <view class="btn-sure" bindtap="onBindOK">确定</view>
    </view>
    //定义事件
    methods() {
       return {
           /*
           *@description:确定事件处理
          */
          async onBindOK () {
            if (this.data.inputCode.valid) {
              this.triggerEvent("onSmsValid");
            }
          },
          async onBindCancel () {
            this.triggerEvent("onCloseSms");
          },
        }
     }
    

    自定义组件可以触发任意的事件,通过triggerEvent方法触发,引用组件的页面可以监听这些事件。如:

    //myevent:引用组件页面定义的监听事件
    var myEventDetail = {} // detail对象,提供给事件监听函数
    var myEventOption = {} // 触发事件的选项
    this.triggerEvent('myevent', myEventDetail, myEventOption)
    //引用组件页面监听事件
    Page({
      onMyEvent: function(e){
        e.detail // 自定义组件触发事件时提供的detail对象
      }
    })
    
    
    //组件事件
      methods() {
        return {
          // 点击跳转到商品详情页面
          onGoodsDetail (e) {
            this.triggerEvent("onGoodsClick", e.currentTarget.dataset.skuid);
          }
        }
      }
    //引用组件页面监听事件
      async onGoodsDetail (e) {
        this.WXX.navigateTo("../detail/detail", {
          skuid: e.detail
        });
      }
    

    3.2页面如何运用组件

    (1)在页面上使用组件,首先两个步骤

    • 引入组件
      在页面对应的json文件中引入
        "usingComponents": {
            "container": "../../components/container/container",
            "verificode": "../../../components/verificode/verificode"
        }
    
    • 页面放置组件
      在wxml文件中放置组件,具体工作:
      1、定义id:id是引入时定义的。
      2、定义属性:页面把数据传递给组件使用,如info
      3、定义组件触发父级的绑定事件:组件可以触发任意的父级事件。通过triggerEvent方法触发,如onSmsValid,onCloseSms等。组件进行某种操作后,父级页面根据情况做下一步操作。
      <!--短信验证码弹框-->
      <verificode id="verificode" info="{{info}}" bind:onSmsValid="onSmsValid" 
      bind:onCloseSms="onCloseSms" wx:if="{{isShowSmsSend}}"></verificode>   </view>
    

    3.3组件初始化事件

    组件和page不一样,没有onload时间,与之对应的attached,ready事件。

      async ready () {
        this.onGetVerificationCode();
      }
    

    attached事件

      /*
       *@description:初始化
       *@date: 2019-12-19 16:02:24
      */
      lifetimes () {
        return {
          attached () {
            this.init();
            wx.getSystemInfo({
              success: (res) => {
                this.setData({ pixelRatio: res.pixelRatio, windowWidth: res.windowWidth })
                this.windowHeight = res.windowHeight;
              }
            })
          }
        }
      }
    

    4.0 通过组件的对外属性,外部可以改变内部私有属性。

    组件内部

      data () {
        return {
          paddingBottom: "0rpx",// 需要底部拉长的页面需要单独加padding
          showDeadline: false,  // 没有更多
          toTop: false, // 返回顶部回顶部
          showComfirmBox: false, // 显示弹窗
        }
      }
      properties () {
        let _this = this;
        return {
          opts: {
            type: Object,
            observer: function parseOpts (opts, oldOpts) {
              /**
               * 外部接收到opts的值,传递进来,
               * 根据不同的需要进行不同的设置
               * 判断opts.type,判断弹窗类型
               * 其余则为内置的控件显示
               */
              if (opts != null) {
                switch (opts.type) {
                  case 'alert':
                  case 'toast':
                  case 'confirm':
                  case 'logistics':
                    ConfirmBox[opts.type](this, opts.content);
                    return;
                  default:
                }
               //把外部获取的属性存放在内部属性上
                this.setData(opts);
              }
            }
          },
        }
      }
    

    这种方式可以把多个属性合并成一个外部属性,在外部可以局部改变某个属性,其他属性不影响。

        //解决iphone X底部遮挡问题
        getApp().globalData.iphoneBottom && _this.setData({
          "BottomBtn.bottomCss": "isIPX",
          opts: {
            paddingBottom: "140rpx"
          }
        });
    //这时候仅仅改变的是paddingBottom属性,其他showDeadline等属性不变。
    

    相关文章

      网友评论

          本文标题:【小程序】自定义组件之component

          本文链接:https://www.haomeiwen.com/subject/rvwadqtx.html