1、前言
從小程序基礎(chǔ)庫版本 1.6.3 開始,小程序支持簡潔的組件化編程。所有自定義組件相關(guān)特性都需要基礎(chǔ)庫版本 1.6.3 或更高。開發(fā)者可以將頁面內(nèi)的功能模塊抽象成自定義組件,以便在不同的頁面中重復(fù)使用;也可以將復(fù)雜的頁面拆分成多個低耦合的模塊,有助于代碼維護。自定義組件在使用時與基礎(chǔ)組件非常相似。
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
2、自定義組件之組件的創(chuàng)建與引用
2.1 創(chuàng)建
步驟:
- 在項目的根目錄中右鍵,創(chuàng)建components–>test文件夾
- 在新建的components–>test文件夾上右鍵,點擊“新建Component”
- 鍵入組件的名稱之后回車,會自動生成組件多對應(yīng)的四個文件:.js,.json,.wxml,.wxss
建議:為了保證目錄結(jié)構(gòu)清晰,建議把不同的組件存放到單獨的目錄中,如下圖所示
2.2 引用
1)局部引用
- 在頁面的.json配置文件中引用自定義組件的方式稱為“局部引用”
- 在頁面的.json文件的usingComponents節(jié)點下聲明組件的標(biāo)簽名與組件的頁面路徑
.json
//在頁面的.json文件中,引入自定義的組件并定義引用時的標(biāo)簽名
{
"usingComponents": {
//自定義組件的標(biāo)簽名字為my-test1
"my-test1":"/components/test1/test1"
},
.wxml
//在頁面的.wxml文件中使用剛剛自定義組件的標(biāo)簽名來引用自定義組件
<my-test1>使用自定義組件1</my-test1>
2)全局引用
- 在app.json全局配置文件中引用組件稱為“全局引用”
- 聲明與使用與局部引用同理,只是聲明是在app.json文件的usingComponents節(jié)點下
- 作用域是全局的每一個頁面
3)應(yīng)用場景
主要根據(jù)組件的使用頻率和范圍來選擇合適的引用方式
- 如果某組件在多個頁面中經(jīng)常使用,則最好將其進行“全局引用”
- 如果某個頁面只在某個特定的頁面中使用,則最好是將其進行“局部引用”
2.3 組件與頁面的區(qū)別
大家會發(fā)現(xiàn)自定義組件和頁面是不是非常相似,同樣都是擁有四個文件 .js .json .wxml .wxss
但是組件與頁面的.js與.json文件有著明顯的區(qū)別:
- 組件的.json文件中需要聲明“components”:true屬性,而頁面不需要
- 組件的.js文件中調(diào)用的是Components()函數(shù),而頁面調(diào)用的是Page()函數(shù)
- 組件的事件處理函數(shù)需要寫在methods節(jié)點中,而頁面則要在與data數(shù)據(jù)節(jié)點平級聲明即可
3、自定義組件之組件的樣式隔離
3.1樣式隔離特性
在默認(rèn)的情況下,自定義組件的樣式只對當(dāng)前的組件生效,而不會去影響到組件之外的UI結(jié)構(gòu)
如下圖:
- A的樣式不會影響C的樣式
- A的樣式不會影響小程序頁面的樣式
- 小程序頁面的樣式不會影響A和C的樣式
特性的好處: - 防止外界的樣式影響自定義組件內(nèi)部的樣式,造成樣式污染
- 也能防止組件樣式破壞外檢的樣式,雙向的
注意點:
- app.wxss中的全局樣式對自定義組件默認(rèn)是無效的
- 只有使用class樣式選擇器才會有樣式隔離的效果,id選擇器、屬性選擇器、標(biāo)簽選擇器不受樣式隔離的影響
所以在自定義組件和引用自定義組件的頁面中最好使用class樣式選擇器,不要使用id,屬性,標(biāo)簽選擇器從而避免造成不必要的麻煩!
3.2 修改隔離選項
默認(rèn)情況下,自定義組件的樣式隔離特性可以有效防止內(nèi)外樣式互相干擾的問題。但是在某些情況下我們又需要在外界能夠控制自定義組件的內(nèi)部樣式,此時就可以通過修改styleIsolation屬性來修改自定義組件樣式隔離選項,從而達到控制內(nèi)部組件樣式的目的。
有兩種方法:
- 第一種:在自定義組件的.js文件中新增如下配置
//.js文件中
Component({
options:{
//表示啟用樣式隔離
styleIsolation:'isolated'
}
})
- 第二種:在自定義組件的.json文件中新增如下配置
//.json文件中
{
"styleIsolation":"isolated"
}
styleIsolation的可選值:
- isolated 表示啟用樣式隔離,在自定義組件內(nèi)外,使用 class 指定的樣式將不會相互影響(一般情況下的默認(rèn)值);
- apply-shared 表示頁面 wxss 樣式將影響到自定義組件,但自定義組件 wxss 中指定的樣式不會影響頁面;
- shared 表示頁面 wxss 樣式將影響到自定義組件,自定義組件 wxss 中指定的樣式也會影響頁面和其他設(shè)置了 apply-shared 或 shared 的自定義組件。(這個選項在插件中不可用。)
使用后兩者時,請務(wù)必注意組件間樣式的相互影響。
如果這個 Component 構(gòu)造器用于構(gòu)造頁面 ,則默認(rèn)值為 shared ,且還有以下幾個額外的樣式隔離選項可用:
- page-isolated 表示在這個頁面禁用 app.wxss ,同時,頁面的 wxss 不會影響到其他自定義組件;
- page-apply-shared 表示在這個頁面禁用 app.wxss ,同時,頁面 wxss 樣式不會影響到其他自定義組件,但設(shè)為 shared 的自定義組件會影響到頁面;
- page-shared 表示在這個頁面禁用 app.wxss ,同時,頁面 wxss 樣式會影響到其他設(shè)為 apply-shared 或shared 的自定義組件,也會受到設(shè)為 shared 的自定義組件的影響。
4、自定義組件之組件的三大節(jié)點屬性
4.1 data數(shù)據(jù)節(jié)點
在小程序組件中,用于組件模板渲染的私有數(shù)據(jù)需要定義到.js文件的data節(jié)點中
// components/test1/test1.js
Component({
/**
* 組件的初始數(shù)據(jù)
*/
data: {
count:0
},
})
4.2 methods方法節(jié)點
在小程序組件中,事件處理函數(shù)和自定義的方法需要定義到.js文件的methods節(jié)點中
// components/test1/test1.js
//點擊按鈕使count加1,并且控制其最大值為屬性中的max值
Component({
/**
* 組件的初始數(shù)據(jù)
*/
data: {
count:0
},
/**
* 組件的屬性列表
*/
properties: {
//方法一:完整方式
max:{
type:Number,//參數(shù)類型
value:0 //參數(shù)的默認(rèn)值
}
},
/**
* 組件的方法列表
*/
methods: {
// 點擊事件的處理函數(shù)
addCount(){
if(this.data.count>=this.properties.max)return
this.setData({
count:this.data.count+1
})
this._showCount()
},
// 自定義的方法建議以下劃線開頭以示區(qū)分
_showCount(){
// 打印消息框
wx.showToast({
title: 'count值為:'+this.data.count,
icon:"none"
})
},
}
})
4.3 properties屬性節(jié)點
在小程序組件中,properties是組件的對外屬性,用來接收外界傳遞到組件中的數(shù)據(jù)
// components/test/test1.js
Component({
/**
* 組件的屬性列表
*/
properties: {
//方法一:完整方式
max:{
type:Number,//參數(shù)類型
value:0 //參數(shù)的默認(rèn)值
}
//方法二:簡化方式
max:Number
},
})
然后在頁面結(jié)構(gòu)中可以在標(biāo)簽內(nèi)直接傳值
<my-test1 max="10"></my-test1>
4.4 data和properties的區(qū)別
在小程序組件中,properties屬性和data數(shù)據(jù)的用法相同,在本質(zhì)上沒有任何區(qū)別,properties里面的值與data一樣可以用于頁面渲染,也可以使用setData()方法為properties屬性中的值進行重新賦值,但有以下兩點區(qū)別:
- data更加傾向于存儲組件的私有數(shù)據(jù)(內(nèi)部數(shù)據(jù))
- properties更加傾向于存儲外界傳遞到組件中的數(shù)據(jù)(外部數(shù)據(jù)、通信)
5、自定義組件之組件的數(shù)據(jù)監(jiān)聽器
5.1 監(jiān)聽數(shù)據(jù)的變化
數(shù)據(jù)監(jiān)聽器,用于監(jiān)聽和響應(yīng)任何屬性與數(shù)據(jù)字段的變化,從而執(zhí)行特定的操作。
基本語法格式:
Component({
observer:{
'字段A,字段B':function(字段A的新值,字段B的新值){
// do something
}
}
})
示例代碼:
test1.wxml
<!--components/test1/test1.wxml-->
<view>{{n1}}+{{n2}}={{sum}}</view>
<button bindtap="addN1" type="primary">n1+1</button>
<button bindtap="addN2" type="primary">n2+1</button>
test1.js
// components/test1/test1.js
Component({
/**
* 組件的屬性列表
*/
properties: {
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
n1:0,
n2:0,
sum:0
},
/**
* 組件的方法列表
*/
methods: {
//n1+1
addN1(){
this.setData({
n1:this.data.n1+1
})
},
//n2+1
addN2(){
this.setData({
n2:this.data.n2+1
})
}
},
//數(shù)據(jù)監(jiān)聽器。監(jiān)聽n1,n2的變化,自動計算sum
observers:{
'n1,n2':function(newN1,newN2){
this.setData({
sum:newN1+newN2
})
}
}
})
app.json聲明自定義組件
"usingComponents": {
"my-test1":"/components/test1/test1"
}
在home.wxml上渲染
<!--pages/home/home.wxml-->
<my-test1></my-test1>
實現(xiàn)效果
當(dāng)任意按下n1+1或者n2+1按鈕時,導(dǎo)致n1,n2數(shù)值的變化從而被數(shù)據(jù)監(jiān)聽器捕捉到,然后在事件監(jiān)聽器處理函數(shù)內(nèi)部對sum用新值進行自動計算賦值
5.2 監(jiān)聽對象屬性的變化
數(shù)據(jù)監(jiān)聽器支持監(jiān)聽對象中單個或者多個屬性的變化,基本語法如下:
Component({
observer:{
'對象.屬性A,對象.屬性B':function(屬性A的新值,屬性B的新值){
// do something
}
}
})
如果某個對象中需要被監(jiān)聽的屬性太多,為了方便,則可以使用通配符 ** 來監(jiān)聽對象中所有屬性的變化,基本語法如下:
Component({
observer:{
'對象.**':function(obj){
this.setData({
某數(shù)據(jù)字段:`${obj.對象屬性1},${obj.對象屬性2}......`
})
}
}
})
6、自定義組件之組件的純數(shù)據(jù)字段
純數(shù)據(jù)字段指的是那些完全不用于頁面渲染的data字段
純數(shù)據(jù)字段可以提升頁面更新的性能
應(yīng)用場景:
- 某些data中的字段不會展示在界面上
- 也不會傳遞給其它組件
- 僅在當(dāng)前組件的內(nèi)部進行使用
使用規(guī)則:
在Component構(gòu)造器的options節(jié)點中,指定pureDataPattern為一個正則表達式,字段名符合這個正則表達式的字段將成為純數(shù)據(jù)字段,示例代碼如下:
Component({
options:{
//這里示例指定所有以 _ 開頭的數(shù)據(jù)字段為純數(shù)據(jù)字段
pureDataPattern:/^_/
},
data:{
a:true,//普通字段
_b:true,//將被設(shè)置為純數(shù)據(jù)字段
}
})
7、自定義組件之組件的生命周期及其函數(shù)
7.1 組件主要生命周期
- 組件實例被創(chuàng)建 – created
- 組件完全初始化完畢 – attached
- 組件進入頁面節(jié)點樹
- 組件離開頁面節(jié)點樹 – detached
7.2 定義生命周期函數(shù)
在小程序組件中,生命周期函數(shù)的定義有新舊兩種方式
- 第一種,直接定義在Component構(gòu)造器內(nèi)與data節(jié)點平級的第一級參數(shù)中
- 第二種,可以在lifetimes字段內(nèi)進行聲明(推薦,其優(yōu)先級最高,且專門放生命周期函數(shù))
自定義組件.js文件:
//定義組件生命周期函數(shù)的兩種方式
Component({
//推薦用法
lifetimes:{
attached(){ },
detached(){ },
}
//舊的定義方式,與data節(jié)點平級
attached(){ },
detached(){ },
})
注:如果同時存在兩種新舊定義方式,那么舊的定義方式將會被覆蓋掉
8、自定義組件之組件的插槽
在自定義組件的wxml結(jié)構(gòu)中,可以提供一個節(jié)點(插槽),用于填充組件使用者提供的wxml結(jié)構(gòu),起到占位的作用
8.1 單個插槽的使用
在小程序中,默認(rèn)每個自定義的組件只能允許使用一個進行占位,這種個數(shù)上的限制就叫做單個插槽
<!-- 組件的封裝者 -->
<view>
<view>這是組件的內(nèi)部節(jié)點</view>
<!-- 下面對于不確定的內(nèi)容可以使用<slot>插槽進行占位,后續(xù)由組件使用者進行填充 -->
<slot></slot>
</view>
<!-- 組件的使用者 -->
<component-tag-name>
<!-- 下面的內(nèi)容將被放置到組件封裝者定義插槽<slot>的位置 -->
<view>這是插入到組件slot中內(nèi)容</view>
</component-tag-name>
8.2 多個插槽的使用
1)啟動多個插槽
小程序的自定義組件默認(rèn)支持一個插槽的使用,如果需要使用多個插槽,就可以在組件.js文件中通過如下方式進行配置從而啟用多個插槽的功能
Component({
options:{
multipleSlots:true//啟用多個插槽
},
properities:{/* ... */},
methods:{/* ... */}
})
定義與使用
<!-- 頁面模板,即組件的封裝者 -->
<view>
<!-- 這是name為slot1的第一個插槽 -->
<slot name="slot1"></slot>
<view>~~~~~~~分隔線~~~~~~~~~</view>
<!-- 這是name為slot2的第二個插槽 -->
<slot name="slot2"></slot>
</view>
<!-- 引用組件的頁面模板,即組件的使用者 -->
<component-tag-name>
<view slot="slot1">這是插入到名字為slot1插槽里面的內(nèi)容</view>
<view slot="slot2">這是插入到名字為slot2插槽里面的內(nèi)容</view>
</component-tag-name>
9、組件間通信與事件
9.1 組件間通信
組件間的基本通信方式有以下幾種。
- WXML 數(shù)據(jù)綁定:用于父組件向子組件的指定屬性設(shè)置數(shù)據(jù),僅能設(shè)置 JSON 兼容數(shù)據(jù)(自基礎(chǔ)庫版本 2.0.9開始,還可以在數(shù)據(jù)中包含函數(shù))。具體在 組件模板和樣式 章節(jié)中介紹。
- 事件:用于子組件向父組件傳遞數(shù)據(jù),可以傳遞任意數(shù)據(jù)。
- 如果以上兩種方式不足以滿足需要,父組件還可以通過 this.selectComponent方法獲取子組件實例對象,這樣就可以直接訪問組件的任意數(shù)據(jù)和方法
9.2 監(jiān)聽事件
事件系統(tǒng)是組件間通信的主要方式之一。自定義組件可以觸發(fā)任意的事件,引用組件的頁面可以監(jiān)聽這些事件。關(guān)于事件的基本概念和用法,參見 事件 。
監(jiān)聽自定義組件事件的方法與監(jiān)聽基礎(chǔ)組件事件的方法完全一致:
<!-- 當(dāng)自定義組件觸發(fā)“myevent”事件時,調(diào)用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />
<!-- 或者可以寫成 -->
<component-tag-name bind:myevent="onMyEvent" />
Page({
onMyEvent: function(e){
e.detail // 自定義組件觸發(fā)事件時提供的detail對象
}
})
9.3 觸發(fā)事件
自定義組件觸發(fā)事件時,需要使用 triggerEvent 方法,指定事件名、detail對象和事件選項:
<!-- 在自定義組件中 -->
<button bindtap="onTap">點擊這個按鈕將觸發(fā)“myevent”事件</button>
Component({
properties: {},
methods: {
onTap: function(){
var myEventDetail = {} // detail對象,提供給事件監(jiān)聽函數(shù)
var myEventOption = {} // 觸發(fā)事件的選項
this.triggerEvent('myevent', myEventDetail, myEventOption)
}
}
})
觸發(fā)事件的選項包括:
9.4 獲取組件實例
可在父組件里調(diào)用 this.selectComponent ,獲取子組件的實例對象。
調(diào)用時需要傳入一個匹配選擇器 selector,如:this.selectComponent(“.my-component”)。
// 父組件
Page({
data: {},
getChildComponent: function () {
const child = this.selectComponent('.my-component');
console.log(child)
}
})
在上例中,父組件將會獲取 class 為 my-component 的子組件實例對象,即子組件的 this 。文章來源:http://www.zghlxwxcb.cn/news/detail-781251.html
注 :默認(rèn)情況下,小程序與插件之間、不同插件之間的組件將無法通過 selectComponent 得到組件實例(將返回 null)。如果想讓一個組件在上述條件下依然能被 selectComponent 返回,可以自定義其返回結(jié)果(見下)文章來源地址http://www.zghlxwxcb.cn/news/detail-781251.html
// 自定義組件 my-component 內(nèi)部
Component({
behaviors: ['wx://component-export'],
export() {
return { myField: 'myValue' }
}
})
<!-- 使用自定義組件時 -->
<my-component id="the-id" />
// 父組件調(diào)用
const child = this.selectComponent('#the-id') // { myField: 'myValue' }
到了這里,關(guān)于微信小程序之自定義組件開發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!