美文网首页
【小程序】自定义组件之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