小程序:自定義組件

ylbtech-小程序:自定義組件

 

1. 自定義組件返回頂部

自定義組件

從小程序基礎庫版本 1.6.3 開始,小程序支持簡潔的組件化編程。html

開發者能夠將頁面內的功能模塊抽象成自定義組件以便在不一樣的頁面中重複使用也能夠將複雜的頁面拆分紅多個低耦合的模塊有助於代碼維護。自定義組件在使用時與基礎組件很是類似。node

建立自定義組件

相似於頁面,一個自定義組件由 json wxml wxss js 4個文件組成。要編寫一個自定義組件,首先須要在 json 文件中進行自定義組件聲明(將 component 字段設爲 true 可這一組文件設爲自定義組件):編程

{
  "component": true
}

同時,還要在 wxml 文件中編寫組件模版在 wxss 文件中加入組件樣式,它們的寫法與頁面的寫法相似。具體細節和注意事項參見 組件模版和樣式 。json

代碼示例:小程序

<!-- 這是自定義組件的內部WXML結構 -->
<view class="inner">
  {{innerText}}
</view>
<slot></slot>
/* 這裏的樣式只應用於這個自定義組件 */
.inner {
  color: red;
}

注意:在組件wxss中不該使用ID選擇器、屬性選擇器和標籤名選擇器api

在自定義組件的 js 文件中,須要使用 Component() 來註冊組件,並提供組件的屬性定義、內部數據和自定義方法數組

組件的屬性值和內部數據將被用於組件 wxml 的渲染,其中,屬性值是可由組件外部傳入的。更多細節參見 Component構造器 。app

代碼示例:xss

Component({
  properties: {
    // 這裏定義了innerText屬性,屬性值能夠在組件使用時指定
    innerText: {
      type: String,
      value: 'default value',
    }
  },
  data: {
    // 這裏是一些組件內部數據
    someData: {}
  },
  methods: {
    // 這裏是一個自定義方法
    customMethod: function(){}
  }
})

使用自定義組件

使用已註冊的自定義組件前,首先要在頁面的 json 文件中進行引用聲明。此時須要提供每一個自定義組件的標籤名和對應的自定義組件文件路徑編程語言

{
  "usingComponents": {
    "component-tag-name": "path/to/the/custom/component"
  }
}

這樣,在頁面的 wxml 中就能夠像使用基礎組件同樣使用自定義組件。節點名即自定義組件的標籤名,節點屬性即傳遞給組件的屬性值。

代碼示例:

<view>
  <!-- 如下是對一個自定義組件的引用 -->
  <component-tag-name inner-text="Some text"></component-tag-name>
</view>

自定義組件的 wxml 節點結構在與數據結合以後將被插入到引用位置內

Tips:

  • 對於基礎庫的1.5.x版本, 1.5.7 也一樣支持自定義組件。
  • 由於WXML節點標籤名只能是小寫字母和下劃線的組合,因此自定義組件的標籤名也只能包含小寫字母和下劃線。
  • 自定義組件也是能夠引用自定義組件的,引用方法相似於頁面引用自定義組件的方式(使用 usingComponents 字段)。
  • 自定義組件和使用自定義組件的頁面所在項目根目錄名不能以「wx-」爲前綴,不然會報錯
  • 舊版本的基礎庫不支持自定義組件,此時,引用自定義組件的節點會變爲默認的空節點
2. 組件模版和樣式返回頂部

組件模版和樣式

相似於頁面,自定義組件擁有本身的 wxml 模版和 wxss 樣式。

組件模版

組件模版的寫法與頁面模板相同。組件模版與組件數據結合後生成的節點樹將被插入到組件的引用位置上

在組件模板中能夠提供一個 <slot> 節點,用於承載組件引用時提供的子節點

代碼示例:

<!-- 組件模板 -->
<view class="wrapper">
  <view>這裏是組件的內部節點</view>
  <slot></slot>
</view>
<!-- 引用組件的頁面模版 -->
<view>
  <component-tag-name>
    <!-- 這部份內容將被放置在組件 <slot> 的位置上 -->
    <view>這裏是插入到組件slot中的內容</view>
  </component-tag-name>
</view>

組件wxml的slot

在組件的wxml中能夠包含 slot 節點,用於承載組件使用者提供的wxml結構

默認狀況下,一個組件的wxml中只能有一個slot。須要使用多slot時,能夠在組件js中聲明啓用

Component({
  options: {
    multipleSlots: true // 在組件定義時的選項中啓用多slot支持
  },
  properties: { /* ... */ },
  methods: { /* ... */ }
})

此時,能夠在這個組件的wxml中使用多個slot,以不一樣的 name 來區分。

<!-- 組件模板 -->
<view class="wrapper">
  <slot name="before"></slot>
  <view>這裏是組件的內部細節</view>
  <slot name="after"></slot>
</view>

使用時,用 slot 屬性來將節點插入到不一樣的slot上

<!-- 引用組件的頁面模版 -->
<view>
  <component-tag-name>
    <!-- 這部份內容將被放置在組件 <slot name="before"> 的位置上 -->
    <view slot="before">這裏是插入到組件slot name="before"中的內容</view>
    <!-- 這部份內容將被放置在組件 <slot name="after"> 的位置上 -->
    <view slot="after">這裏是插入到組件slot name="after"中的內容</view>
  </component-tag-name>
</view>

組件樣式

組件對應 wxss 文件的樣式只對組件wxml內的節點生效。編寫組件樣式時,須要注意如下幾點:

  • 組件和引用組件的頁面不能使用id選擇器(#a)、屬性選擇器([a])和標籤名選擇器請改用class選擇器
  • 組件和引用組件的頁面中使用後代選擇器(.a .b在一些極端狀況下會有非預期的表現,如遇,請避免使用。
  • 子元素選擇器(.a>.b只能用於 view 組件與其子節點之間,用於其餘組件可能致使非預期的狀況。
  • 繼承樣式,如 font 、 color ,會從組件外繼承到組件內。
  • 除繼承樣式外, app.wxss 中的樣式、組件所在頁面的的樣式對自定義組件無效
#a { } /* 在組件中不能使用 */
[a] { } /* 在組件中不能使用 */
button { } /* 在組件中不能使用 */
.a > .b { } /* 除非 .a 是 view 組件節點,不然不必定會生效 */

除此之外,組件能夠指定它所在節點的默認樣式,使用 :host 選擇器(須要 1.7.2 或更高版本的開發者工具支持)。

代碼示例:

/* 組件 custom-component.wxss */
:host {
  color: yellow;
}
:host(.dark) {
  color: black;
}
<!-- 頁面的 WXML -->
<custom-component>這段文本是黃色的</custom-component>
<custom-component class="dark">這段文本是黑色的</custom-component>

 

3. Component構造器返回頂部

Component構造器

Component構造器可用於定義組件,調用Component構造器時能夠指定組件的屬性、數據、方法等

定義段 類型 是否必填 描述
properties Object Map 組件的對外屬性,是屬性名到屬性設置的映射表,屬性設置中可包含三個字段, type表示屬性類型、 value 表示屬性初始值、 observer 表示屬性值被更改時的響應函數
data Object 組件的內部數據,和 properties 一同用於組件的模版渲染
methods Object 組件的方法,包括事件響應函數和任意的自定義方法,關於事件響應函數的使用,參見 組件事件
behaviors String Array 相似於mixins和traits組件間代碼複用機制,參見 behaviors
created Function 組件生命週期函數,在組件實例進入頁面節點樹時執行,注意此時不能調用 setData
attached Function 組件生命週期函數,在組件實例進入頁面節點樹時執行
ready Function 組件生命週期函數,在組件佈局完成後執行,此時能夠獲取節點信息(使用 SelectorQuery )
moved Function 組件生命週期函數,在組件實例被移動到節點樹另外一個位置時執行
detached Function 組件生命週期函數,在組件實例被從頁面節點樹移除時執行
relations Object 組件間關係定義,參見 組件間關係
options Object Map 一些組件選項,請參見文檔其餘部分的說明

生成的組件實例能夠在組件的方法、生命週期函數和屬性 observer 中經過 this 訪問。組件包含一些通用屬性和方法。

屬性名 類型 描述
is String 組件的文件路徑
id String 節點id
dataset String 節點dataset
data Object 組件數據,包括內部數據和屬性值

 

方法名 參數 描述
setData Object newData 設置data並執行視圖層渲染
hasBehavior Object behavior 檢查組件是否具備 behavior (檢查時會遞歸檢查被直接或間接引入的全部behavior
triggerEvent String name, Object detail, Object options 觸發事件,參見 組件事件
createSelectorQuery   建立一個 SelectorQuery 對象,選擇器選取範圍爲這個組件實例內
selectComponent String selector 使用選擇器選擇組件實例節點,返回匹配到的第一個組件實例對象
selectAllComponents String selector 使用選擇器選擇組件實例節點,返回匹配到的所有組件實例對象組成的數組
getRelationNodes String relationKey 獲取全部這個關係對應的全部關聯節點,參見 組件間關係

代碼示例:

Component({

  behaviors: [],

  properties: {
    myProperty: { // 屬性名
      type: String, // 類型(必填),目前接受的類型包括:String, Number, Boolean, Object, Array, null(表示任意類型)
      value: '' // 屬性初始值(可選),若是未指定則會根據類型選擇一個
      observer: function(newVal, oldVal){} // 屬性被改變時執行的函數(可選),也能夠寫成在methods段中定義的方法名字符串
    },
    myProperty2: String // 簡化的定義方式
  },
  data: {}, // 私有數據,可用於模版渲染

  // 生命週期函數,能夠爲函數,或一個在methods段中定義的方法名
  attached: function(){},
  moved: function(){},
  detached: function(){},

  methods: {
    onMyButtonTap: function(){
      this.setData({
        // 更新屬性和數據的方法與更新頁面數據的方法相似
      })
    },
    _myPrivateMethod: function(){
      // 內部方法建議如下劃線開頭
      this.replaceDataOnPath(['A', 0, 'B'], 'myPrivateData') // 這裏將 data.A[0].B 設爲 'myPrivateData'
      this.applyDataUpdates()
    }
  }

})

注意:在 properties 定義段中,屬性名採用駝峯寫法(propertyName;在 wxml 中指定屬性值時則對應使用連字符寫法(component-tag-name property-name="attr value"應用於數據綁定時採用駝峯寫法(attr="{{propertyName}}"

Tips:

  • Component 構造器構造的組件也能夠做爲頁面使用
  • 使用 this.data 能夠獲取內部數據和屬性值,但不要直接修改它們,應使用 setData 修改。
  • 生命週期函數沒法在組件方法中經過 this 訪問到。
  • 屬性名不要命名成 dataXyz 這樣的形式,由於在 WXML 中, data-xyz="" 會被做爲節點 dataset 來處理,而不是組件屬性。
  • 在一個組件的定義和使用時,組件的屬性名和data字段相互間都不能衝突儘管它們位於不一樣的定義段中)。
4. 組件事件返回頂部

組件事件

事件系統組件間交互主要形式。自定義組件能夠觸發任意的事件,引用組件的頁面能夠監聽這些事件。關於事件的基本概念和用法,參見 事件 。

監聽自定義組件事件的方法與監聽基礎組件事件的方法徹底一致:

代碼示例:

<!-- 當自定義組件觸發「myevent」事件時,調用「onMyEvent」方法 -->
<component-tag-name bindmyevent="onMyEvent" />
<!-- 或者能夠寫成 -->
<component-tag-name bind:myevent="onMyEvent" />
Page({
  onMyEvent: function(e){
    e.detail // 自定義組件觸發事件時提供的detail對象
  }
})

自定義組件觸發事件時,須要使用 triggerEvent 方法,指定事件名、detail對象和事件選項

代碼示例:

<!-- 在自定義組件中 -->
<button bindtap="onTap">點擊這個按鈕將觸發「myevent」事件</button>
Component({
  properties: {}
  methods: {
    onTap: function(){
      var myEventDetail = {} // detail對象,提供給事件監聽函數
      var myEventOption = {} // 觸發事件的選項
      this.triggerEvent('myevent', myEventDetail, myEventOption)
    }
  }
})

觸發事件的選項包括:

選項名 類型 是否必填 默認值 描述
bubbles Boolean false 事件是否冒泡
composed Boolean false 事件是否能夠穿越組件邊界,爲false時,事件將只能在引用組件的節點樹上觸發,不進入其餘任何組件內部
capturePhase Boolean false 事件是否擁有捕獲階段

關於冒泡和捕獲階段的概念,請閱讀 事件 章節中的相關說明。

代碼示例:

// 頁面 page.wxml
<another-component bindcustomevent="pageEventListener1">
  <my-component bindcustomevent="pageEventListener2"></my-component>
</another-component>
// 組件 another-component.wxml
<view bindcustomevent="anotherEventListener">
  <slot />
</view>
// 組件 my-component.wxml
<view bindcustomevent="myEventListener">
  <slot />
</view>
// 組件 my-component.js
Component({
  methods: {
    onTap: function(){
      this.triggerEvent('customevent', {}) // 只會觸發 pageEventListener2
      this.triggerEvent('customevent', {}, { bubbles: true }) // 會依次觸發 pageEventListener2 、 pageEventListener1
      this.triggerEvent('customevent', {}, { bubbles: true, composed: true }) // 會依次觸發 pageEventListener2 、 anotherEventListener 、 pageEventListener1
    }
  }
})

 

5. behaviors返回頂部

behaviors

定義和使用 behaviors

behaviors 是用於組件間代碼共享的特性,相似於一些編程語言中的「mixins」或「traits」。

每一個 behavior 能夠包含一組屬性、數據、生命週期函數和方法,組件引用它時,它的屬性、數據和方法會被合併到組件中,生命週期函數也會在對應時機被調用。每一個組件能夠引用多個 behavior 。 behavior 也能夠引用其餘 behavior 。

behavior 須要使用 Behavior() 構造器定義

代碼示例:

// my-behavior.js
module.exports = Behavior({
  behaviors: [],
  properties: {
    myBehaviorProperty: {
      type: String
    }
  },
  data: {
    myBehaviorData: {}
  },
  attached: function(){},
  methods: {
    myBehaviorMethod: function(){}
  }
})

組件引用時,在 behaviors 定義段中將它們逐個列出便可。

代碼示例:

// my-component.js
var myBehavior = require('my-behavior')
Component({
  behaviors: [myBehavior],
  properties: {
    myProperty: {
      type: String
    }
  },
  data: {
    myData: {}
  },
  attached: function(){},
  methods: {
    myMethod: function(){}
  }
})

在上例中, my-component 組件定義中加入了 my-behavior ,而 my-behavior 中包含有 myBehaviorProperty 屬性、 myBehaviorData數據字段、 myBehaviorMethod 方法和一個 attached 生命週期函數。這將使得 my-component 中最終包含 myBehaviorProperty 、 myProperty 兩個屬性, myBehaviorData 、 myData 兩個數據字段,和 myBehaviorMethod 、 myMethod 兩個方法。當組件觸發 attached 生命週期時,會依次觸發 my-behavior 中的 attached 生命週期函數和 my-component 中的 attached 生命週期函數。

字段的覆蓋和組合規則

組件和它引用的 behavior 中能夠包含同名的字段,對這些字段的處理方法以下:

  • 若是有同名的屬性或方法,組件自己的屬性或方法會覆蓋 behavior 中的屬性或方法,若是引用了多個 behavior ,在定義段中靠後 behavior 中的屬性或方法會覆蓋靠前的屬性或方法;
  • 若是有同名的數據字段,若是數據是對象類型,會進行對象合併,若是是非對象類型則會進行相互覆蓋
  • 生命週期函數不會相互覆蓋,而是在對應觸發時機被逐個調用。若是同一個 behavior 被一個組件屢次引用,它定義的生命週期函數只會被執行一次。

內置 behaviors

自定義組件能夠經過引用內置的 behavior 來得到內置組件的一些行爲。

代碼示例:

Component({
  behaviors: ['wx://form-field']
})

在上例中, wx://form-field 表明一個內置 behavior ,它使得這個自定義組件有相似於表單控件的行爲。

內置 behavior 每每會爲組件添加一些屬性。在沒有特殊說明時,組件能夠覆蓋這些屬性來改變它的 type 或添加 observer 。

wx://form-field

使自定義組件有相似於表單控件的行爲。 form 組件能夠識別這些自定義組件,並在 submit 事件返回組件的字段名及其對應字段值。這將爲它添加如下兩個屬性。

屬性名 類型 描述 最低版本
name String 在表單中的字段名 1.6.7
value 任意 在表單中的字段值 1.6.7
 
6. 組件間關係返回頂部

組件間關係

定義和使用組件間關係

有時須要實現這樣的組件:

<custom-ul>
  <custom-li> item 1 </custom-li>
  <custom-li> item 2 </custom-li>
</custom-ul>

這個例子中, custom-ul 和 custom-li 都是自定義組件,它們有相互間的關係,相互間的通訊每每比較複雜。此時在組件定義時加入 relations 定義段,能夠解決這樣的問題。示例:

// path/to/custom-ul.js
Component({
  relations: {
    './custom-li': {
      type: 'child', // 關聯的目標節點應爲子節點
      linked: function(target) {
        // 每次有custom-li被插入時執行,target是該節點實例對象,觸發在該節點attached生命週期以後
      },
      linkChanged: function(target) {
        // 每次有custom-li被移動後執行,target是該節點實例對象,觸發在該節點moved生命週期以後
      },
      unlinked: function(target) {
        // 每次有custom-li被移除時執行,target是該節點實例對象,觸發在該節點detached生命週期以後
      }
    }
  },
  methods: {
    _getAllLi: function(){
      // 使用getRelationNodes能夠得到nodes數組,包含全部已關聯的custom-li,且是有序的
      var nodes = this.getRelationNodes('path/to/custom-li')
    }
  },
  ready: function(){
    this._getAllLi()
  }
})
// path/to/custom-li.js
Component({
  relations: {
    './custom-ul': {
      type: 'parent', // 關聯的目標節點應爲父節點
      linked: function(target) {
        // 每次被插入到custom-ul時執行,target是custom-ul節點實例對象,觸發在attached生命週期以後
      },
      linkChanged: function(target) {
        // 每次被移動後執行,target是custom-ul節點實例對象,觸發在moved生命週期以後
      },
      unlinked: function(target) {
        // 每次被移除時執行,target是custom-ul節點實例對象,觸發在detached生命週期以後
      }
    }
  }
})

注意:必須在兩個組件定義中都加入relations定義,不然不會生效。

關聯一類組件

有時,須要關聯的是一類組件,如:

<custom-form>
  <view>
    input
    <custom-input></custom-input>
  </view>
  <custom-submit> submit </custom-submit>
</custom-form>

custom-form 組件想要關聯 custom-input 和 custom-submit 兩個組件。此時,若是這兩個組件都有同一個behavior

// path/to/custom-form-controls.js
module.exports = Behavior({
  // ...
})
// path/to/custom-input.js
var customFormControls = require('./custom-form-controls')
Component({
  behaviors: [customFormControls],
  relations: {
    './custom-form': {
      type: 'ancestor', // 關聯的目標節點應爲祖先節點
    }
  }
})
// path/to/custom-submit.js
var customFormControls = require('./custom-form-controls')
Component({
  behaviors: [customFormControls],
  relations: {
    './custom-form': {
      type: 'ancestor', // 關聯的目標節點應爲祖先節點
    }
  }
})

則在 relations 關係定義中,可以使用這個behavior來代替組件路徑做爲關聯的目標節點:

// path/to/custom-form.js
var customFormControls = require('./custom-form-controls')
Component({
  relations: {
    'customFormControls': {
      type: 'descendant', // 關聯的目標節點應爲子孫節點
      target: customFormControls
    }
  }
})

relations 定義段

relations 定義段包含目標組件路徑及其對應選項,可包含的選項見下表。

選項 類型 是否必填 描述
type String 目標組件的相對關係,可選的值爲 parent 、 child 、 ancestor 、 descendant
linked Function 關係生命週期函數,當關系被創建在頁面節點樹中時觸發,觸發時機在組件attached生命週期以後
linkChanged Function 關係生命週期函數,當關系在頁面節點樹中發生改變時觸發,觸發時機在組件moved生命週期以後
unlinked Function 關係生命週期函數,當關系脫離頁面節點樹時觸發,觸發時機在組件detached生命週期以後
target String 若是這一項被設置,則它表示關聯的目標節點所應具備的behavior,全部擁有這一behavior的組件節點都會被關聯

 

7.返回頂部
 
8.返回頂部
 
9.返回頂部
 
10.返回頂部
一、
二、
 
11.返回頂部
 
warn 做者:ylbtech
出處:http://ylbtech.cnblogs.com/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索