微信小程序自定義組件詳解

最近開(kāi)發(fā)小程序項(xiàng)目,小程序的的文檔挺詳細(xì)的,特別是官方提供了很多組件。但是,對(duì)于一些項(xiàng)目適用場(chǎng)景,官方所提供的組件是無(wú)法滿足的。這時(shí)候,需要我們自己去開(kāi)發(fā)一個(gè)自定義組件,來(lái)滿足當(dāng)前項(xiàng)目的需求。

如何創(chuàng)建一個(gè)自定義組件

從小程序基礎(chǔ)庫(kù)版本 1.6.3 開(kāi)始,小程序支持簡(jiǎn)潔的組件化編程。所有自定義組件相關(guān)特性都需要基礎(chǔ)庫(kù)版本 1.6.3 或更高。
開(kāi)發(fā)者可以將頁(yè)面內(nèi)的功能模塊抽象成自定義組件,以便在不同的頁(yè)面中重復(fù)使用;也可以將復(fù)雜的頁(yè)面拆分成多個(gè)低耦合的模塊,有助于代碼維護(hù)。自定義組件在使用時(shí)與基礎(chǔ)組件非常相似。

首先,我們需要新建一個(gè) components 文件夾,用于存放我們以后開(kāi)發(fā)中的所用組件,我們?cè)?components 組件中新建一個(gè) module文件夾來(lái)存放我們的組件,在 module下右擊新建 Component 并命名為 module后,會(huì)生成對(duì)應(yīng)的 json wxml wxss js 4個(gè)文件,這就是一個(gè)自定義組件的組成部分,這樣組件初始化工作已完成。同時(shí)我們還需要聲明組件,需要在module. json 文件中進(jìn)行自定義組件聲明(將 component 字段設(shè)為 true ):

{
  "component": true,
  "usingComponents": {}
}

同時(shí),還要在 wxml 文件中編寫組件模版,在 wxss 文件中加入組件樣式,它們的寫法與頁(yè)面的寫法類似。具體細(xì)節(jié)和注意事項(xiàng)參見(jiàn) 組件模版和樣式 。下面為一個(gè)組件的完整結(jié)構(gòu)。

<!-- 這是自定義組件的內(nèi)部WXML結(jié)構(gòu) -->
<view class="inner">
  {{innerText}}
<button type='primary' bindtap='change'>子組件點(diǎn)擊按鈕</button>
</view>
<slot></slot>
<slot name="homePage"></slot>
/* 這里的樣式只應(yīng)用于這個(gè)自定義組件wxss結(jié)構(gòu) */
.inner {
  color: red;
}

在自定義組件的js文件中,需要使用 Component() 來(lái)注冊(cè)組件,并提供組件的屬性定義、內(nèi)部數(shù)據(jù)和自定義方法,

/* 這個(gè)自定義組件js結(jié)構(gòu) */
Component({
  options: {
    multipleSlots: true // 在組件定義時(shí)的選項(xiàng)中啟用多slot支持
  },
  properties: {
    // 這里定義了innerText屬性,屬性值可以在組件使用時(shí)指定
    innerText: {
      type: String,
      value: 'default value',
    }
  },
  data: {
    // 這里是一些組件內(nèi)部數(shù)據(jù)
    someData: {}
  },
  methods: {
    // 這里是一個(gè)自定義方法
    change: function(){
      // 子組件觸發(fā)事件傳給父頁(yè)面
      this.triggerEvent("change")  
    },
  // 子組件自己的方法
  childrenFunction(){
      console.log('我被父組件調(diào)用了')
    }
  }
})

如何使用一個(gè)自定義組件

既然是組件,必然是在頁(yè)面引入使用的,我們一般稱該頁(yè)面為父頁(yè)面。首先,我們應(yīng)該在要用組件的那個(gè)頁(yè)面中(父頁(yè)面)引用聲明.也就是在.json文件。如index.json文件:

  "usingComponents": {
    "module": "/components/module/module"
  }

當(dāng)我們引入組件之后,就可在父頁(yè)面使用該自定義組件了。

父頁(yè)面如何將數(shù)據(jù)傳給子組件呢?
父頁(yè)面通過(guò)inner-text將數(shù)據(jù)傳給子組件,子組件通過(guò)innerText來(lái)接受父頁(yè)面?zhèn)鬟^(guò)來(lái)的父頁(yè)面變量text的數(shù)據(jù)。

父頁(yè)面該如何獲取子組的data,以及子組件的方法?
我們?cè)谝虢M件時(shí),給子組件設(shè)置一個(gè)id,通過(guò)this.selectComponent('#module')的方法來(lái)獲取module組件,即獲得了該組件里的所有內(nèi)容,包括data里的內(nèi)容(this.module.data),以及方法的調(diào)用(this.module.childrenFunction())。

子組件如何調(diào)用父頁(yè)面的方法呢?
通過(guò)this.triggerEvent("change")方法,將子組件觸發(fā)的事件傳給父頁(yè)面,父頁(yè)面通過(guò)bind綁定一個(gè)方法來(lái)接受子組件傳過(guò)來(lái)的change事件方法,從而調(diào)用到父組件的方法。triggerEvent()函數(shù)有三個(gè)參數(shù),第一個(gè)參數(shù)為暴露給父節(jié)點(diǎn)的事件類型。第二個(gè)參數(shù)為向父組件傳遞的數(shù)據(jù),第三個(gè)參數(shù)為選項(xiàng),傳入對(duì)象進(jìn)去。

組件slot的理解?
slot與vue插槽很類似,有了slot的話,可以使組件更加靈活使用。例如,一個(gè)組件的的某些內(nèi)容在不同頁(yè)面引用所展示的內(nèi)容不一樣,這時(shí)我們使用slot來(lái)實(shí)現(xiàn)。name為homePage的slot,我們?cè)趇ndex.wxml使用了,而在別的頁(yè)面未使用的話,別的頁(yè)面就不會(huì)顯示<view name="homePage"></view>里的內(nèi)容。

具體如下:

<!-- 父頁(yè)面 -->
<!-- 頁(yè)面的 WXML -->
<view class="container">
        <module
        id='module'
        inner-text="{{text}}"
        bind:change="change">
        <view>這里是插入到組件slot中的內(nèi)容</view>
        <view name='homePage'>這里插入到組件homePage的slot中的內(nèi)容</view>
    </module>
    <button type='primary' style='height: 40px;' bindtap='childrenFunction'>父頁(yè)面調(diào)用子組件方法</button>
</view>
//index.js
// 獲取應(yīng)用實(shí)例
const app = getApp()
Page({
  data: {
    text: '初始值1'
  }
  /* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面初次渲染完成*/
  onReady: function () {
    // 獲得module組件
    this.module = this.selectComponent('#module');
  }
  // 點(diǎn)擊事件
  change() {
       console.log('moudule組件點(diǎn)擊事件')
      this.setData({
        text: '子組件點(diǎn)擊事件改變了我'    
      })
   }
   // 父頁(yè)面調(diào)用子組件的方法
   childrenFunction(){
    this.module.childrenFunction()
  }
})
后記

微信小程序中自定義組件的用法還有很多, 調(diào)用Component構(gòu)造器時(shí)可以指定組件的屬性、數(shù)據(jù)、方法等,更多的內(nèi)容可以參考官方文檔.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容