一、自定義組件
- 在項(xiàng)目的根目錄中,創(chuàng)建components 文件夾夏伊。
- 在新建的 components 文件夾上,鼠標(biāo)右鍵草慧,點(diǎn)擊“新建 Component”。
- 新建 Component的會自動生成組件對應(yīng)的4個文件缩宜,后綴名分別為js释涛,json燕偶,.wxml和.wxss桥言。
1.1鸳粉、引用組件
組件的引用方式分為“局部引用”和“全局引用湖雹,顧名思義:
- 局部引用:組件只能在當(dāng)前被引用的頁面內(nèi)使用征讲。
- 全局引用:組件可以在每個小程序頁面中使用。
在頁面的 .json 配置文件中引用組件的方式,叫做“局部引用”。
//在頁面的 .json 文件中痘括,引入組件
"usingComponents": {
"component-test":"/components/test1/test1"
},
//在頁面的 .wxml 文件中长窄,使用組件
<component-test></component-test>
在 app.json 全局配置文件中引用組件的方式,叫做“全局引用”纲菌。
"usingComponents": {
"component-test":"/components/test1/test1"
},
"pages": [
"pages/home/home",
"pages/message/message",
"pages/contact/contact",
"pages/info/info"
],
//在頁面的 .wxml 文件中挠日,使用組件
<component-test></component-test>
根據(jù)組件的使用頻率和范圍,來選擇合適的引用方式:驰后。如果某組件在多個頁面中經(jīng)常被用到肆资,建議進(jìn)行“全局引用”如果某組件只在特定的頁面中被用到,建議進(jìn)行“局部引用灶芝。
組件和頁面的區(qū)別郑原,從表面來看唉韭,組件和頁面都是由js、json犯犁、.wxml和.wxss這四個文件組成的属愤。但是,組件和頁面的 js與.json 文件有明顯的不同:
- 組件的 .json 文件中需要聲明"component":true 屬性酸役。
- 組件的 .js 文件中調(diào)用的是 Component()函數(shù)住诸。
- 組件的事件處理函數(shù)需要定義到 methods 節(jié)點(diǎn)中。
1.2涣澡、組件樣式隔離
默認(rèn)情況下贱呐,自定義組件的樣式只對當(dāng)前組件生效,不會影響到組件之外的入桂。UI結(jié)構(gòu)奄薇,如圖所示:
- 組件 A的樣式不會影響組件C的樣式。
- 組件 A 的樣式不會影響小程序頁面的樣式抗愁。
- 小程序頁面的樣式不會影響組件 A和C的樣式馁蒂。
好處:
防止外界的樣式影響組件內(nèi)部的樣式。
防止組件的樣式破壞外界的樣式蜘腌。
1.2.1沫屡、組件樣式隔離的注意點(diǎn)
- app.wxss 中的全局樣式對組件無效
- 只有 class 選擇器會有樣式隔離效果,id 選擇器撮珠、屬性選擇器沮脖、標(biāo)簽選擇器不受樣式隔離的影響。
建議:在組件和引用組件的頁面中建議使用 class 選擇器劫瞳,不要使用id倘潜、屬性绷柒、標(biāo)簽選擇器!
1.2.2志于、修改組件的樣式隔離選項(xiàng)
默認(rèn)情況下,自定義組件的樣式隔離特性能夠防止組件內(nèi)外樣式互相干擾的問題废睦。但有時伺绽,我們希望在外界能夠控制組件內(nèi)部的樣式,此時嗜湃,可以通過 stylelsolation 修改組件的樣式隔離選項(xiàng)奈应,用法如下:
//在組件的js文件中增加如下配置
Component({
options:{
styleIsolation:"apply-shared"
},
// 或在組件的 .ison 文件中新增如下配置
{
"stylelsolation":"apply-shared"
}
styleIsolation的可選值如下:
1.3、組件數(shù)據(jù)购披、方法和屬性
- 在小程序組件中杖挣,用于組件模板渲染的私有數(shù)據(jù)需要定義到 data 節(jié)點(diǎn)中,示例如下:
/**
* 組件的初始數(shù)據(jù)
*/
data: {
count:0,
},
- 在小程序組件中刚陡,事件處理函數(shù)和自定義方法需要定義到 methods 節(jié)點(diǎn)中惩妇,示例代碼如下:
/**
* 組件的方法列表
*/
methods: { // 組件的方法列表【包含事件處理函數(shù)和自定義方法】
addCount(){//事件處理函數(shù)
this.setData({count:this.data.count+1})
this._showCount() // 通過 this 直接調(diào)用自定義方法
},
_showCount(){
wx.showToast({
title:'count值為:'+this.data.count,
icon:'none'
})
}
},
- properties 屬性
在小程序組件中株汉,properties 是組件的對外屬性,用來接收外界傳遞到組件中的數(shù)據(jù)歌殃,乔妈,示例代碼如下:
/**
* 組件的屬性列表
*/
properties:{
max: {
//完整定義屬性的方式【當(dāng)需要指定屬性默認(rèn)值時,建議使用此方式】
type:Number, //屬性值的數(shù)據(jù)類型
value: 10 // 屬性默認(rèn)值
}
//簡化定義屬性的方式【不需指定屬性默認(rèn)值時氓皱,可以使用簡化方式】
// max:Number
},
<component-test max = "10"></component-test>
js文件中獲取該屬性 this.properties.max
data和 properties 的區(qū)別
在小程序的組件中路召,properties 屬性和 data 數(shù)據(jù)的用法相同,它們都是可讀可寫的波材,只不過:data 更傾向于存儲組件的私有數(shù)據(jù)股淡。properties 更傾向于存儲外界傳遞到組件中的數(shù)據(jù)。使用 setData 修改 properties 的值
由于 data 數(shù)據(jù)和 properties 屬性在本質(zhì)上沒有任何區(qū)別廷区,因此 properties 屬性的值也可以用于頁面渲染或使用 setData 為 properties 中的屬性重新賦值揣非,示例代碼如下:
<view>max屬性的值{{max}}</view>
this.setData({max:this.properties.max+1})
1.4、數(shù)據(jù)監(jiān)聽器
- 數(shù)據(jù)監(jiān)聽器用于監(jiān)聽和響應(yīng)任何屬性和數(shù)據(jù)字段的變化躲因,從而執(zhí)行特定的操作早敬。它的作用類似于 vue 中的watch 偵聽器。在小程序組件中大脉,數(shù)據(jù)監(jiān)聽器的基本語法格式如下:
Component({
observers:{"字段A搞监,字段B':function(字段A的新值,字段B的新值){
// do something
}
})
- 數(shù)據(jù)監(jiān)聽器基本用法
<view>num1與num2和為:{{sum}}</view>
<button bind:tap="addNum1">num1</button>
<button bind:tap="addNum2">num2</button>
<view>num1值為:{{num1}}</view>
<view>num2值為:{{num2}}</view>
組件js內(nèi)容如下:
/**
* 組件的初始數(shù)據(jù)
*/
data: {
num1:0,
num2:0,
sum:0
},
/**
* 組件的方法列表
*/
methods: {
addNum1(){this.setData({num1:this.data.num1+1})},
addNum2(){this.setData({num2:this.data.num2+1})}
},
observers:{ //數(shù)據(jù)監(jiān)聽節(jié)點(diǎn)
'num1,num2':function(num1,num2){ //監(jiān)聽num1與num2數(shù)據(jù)變化
this.setData({sum:num1+num2}) //自動計算sum值
}
}
- 監(jiān)聽對象屬性的變化
數(shù)據(jù)監(jiān)聽器支持監(jiān)聽對象中單個或多個屬性的變化镰矿,示例語法如下:
Component({
observers:{
'對象.屬性A琐驴,對象.屬性B': function(屬性A的新值,屬性B的新值){
//觸發(fā)此監(jiān)聽器的 3 種情況:
//【為屬性A賦值】使用 setData 設(shè)置 this.data.對象.屬性A 時觸發(fā)//【為屬性B賦值】使用 setData 設(shè)置 this.data.對象.屬性B 時觸發(fā)
//【直接為對象賦值】使用 setData 設(shè)置 this.data.對象 時觸發(fā)
// do something...
}
}
})
如果某個對象中需要被監(jiān)聽的屬性太多秤标,為了方便绝淡,可以使用通配符 **來監(jiān)聽對象中所有屬性的變化,示例代碼如下:
observers:{
// 使用通配符 ** 完成監(jiān)聽對象上所有屬性的變化
'rgb.**': function(obj){
this.setData({
fullColor:`${obj.r}, ${obj.g},${obj.b}
})
}
}
純數(shù)據(jù)字段
概念:純數(shù)據(jù)字段指的是那些不用于界面渲染的 data 字段苍姜。
應(yīng)用場景:例如有些情況下牢酵,某些 data 中的字段既不會展示在界面上,也不會傳遞給其他組件衙猪,僅僅在當(dāng)前組件內(nèi)部使用馍乙。帶有這種特性的 data 字段適合被設(shè)置為純數(shù)據(jù)字段。
好處:純數(shù)據(jù)字段有助于提升頁面更新的性能垫释。使用規(guī)則
在 Component 構(gòu)造器的 options 節(jié)點(diǎn)中丝格,指定 pureDataPattern 為一個正則表達(dá)式,字段名符合這個正則表達(dá)式的字段將成為純數(shù)據(jù)字段棵譬,示例代碼如下:
Component({
options:{
//指定所有以_開頭的字段為純數(shù)據(jù)字段
pureDataPattern:/^_/
},
data:{
a:1, //普通數(shù)據(jù)字段
_b:2 //純數(shù)據(jù)字段
}
})
1.5显蝌、組件的生命周期
-
小程序組件可用的全部生命周期如下表所示:
在小程序組件中,最重要的生命周期函數(shù)有3個订咸,分別是created曼尊、attached扭屁、detached。它們各自的特點(diǎn)如下:
- 組件實(shí)例剛被創(chuàng)建好的時候涩禀,created 生命周期函數(shù)會被觸發(fā)料滥。
此時還不能調(diào)用 setData
通常在這個生命周期函數(shù)中,只應(yīng)該用于給組件的 this 添加一些自定義的屬性字段 - 在組件完全初始化完畢艾船、進(jìn)入頁面節(jié)點(diǎn)樹后葵腹,attached生命周期函數(shù)會被觸發(fā)。
此時屿岂,this.data 已被初始化完畢
這個生命周期很有用践宴,絕大多數(shù)初始化的工作可以在這個時機(jī)進(jìn)行(例如發(fā)請求獲取初始數(shù)據(jù)) - 在組件離開頁面節(jié)點(diǎn)樹后,detached 生命周期函數(shù)會被觸發(fā)爷怀。
退出一個頁面時阻肩,會觸發(fā)頁面內(nèi)每個自定義組件的 detached 生命周期函數(shù)
此時適合做一些清理性質(zhì)的工作 - lifetimes 節(jié)點(diǎn)
在小程序組件中,生命周期函數(shù)可以直接定義在Component構(gòu)造器的第一級參數(shù)中运授,可以在 lifetimes 字段內(nèi)進(jìn)行聲明(這是推薦的方式烤惊,其優(yōu)先級最高)。示例代碼如下:
Component({
// 推薦用法
lifetimes:{
attached(){}吁朦,//在組件實(shí)例進(jìn)入頁面節(jié)點(diǎn)樹時執(zhí)行
detached(){}柒室,//在組件實(shí)例被從頁面節(jié)點(diǎn)樹移除時執(zhí)行
},
// 以下是舊式的定義方式
attached(){}逗宜,//在組件實(shí)例進(jìn)入頁面節(jié)點(diǎn)樹時執(zhí)行
detached(){}雄右,//在組件實(shí)例被從頁面節(jié)點(diǎn)樹移除時執(zhí)行
})
1.6、組件所在頁面的生命周期
-
有時自定義組件的行為依賴于頁面狀態(tài)的變化纺讲,此時就需要用到組件所在頁面的生命周期擂仍。
在自定義組件中,組件所在頁面的生命周期函數(shù)有如下3個熬甚,分別是:
- pageLifetimes 節(jié)點(diǎn)
組件所在頁面的生命周期函數(shù)逢渔,需要定義在 pageLifetimes 節(jié)點(diǎn)中,示例代碼如下:
Component({
pageLifetimes:{
show:function(){}则涯,//頁面被展示
hide:function(){}复局,// 頁面被隱藏
resize:function(size){}// 頁面尺寸變化
}
})
1.7、插槽
在自定義組件的 wxml結(jié)構(gòu)中粟判,可以提供一個<slot>節(jié)點(diǎn)(插槽),用于承載組件使用者提供的 wxml結(jié)構(gòu)峦剔。
- 單個插槽
在小程序中档礁,默認(rèn)每個自定義組件中只允許使用一個<slot>進(jìn)行占位,這種個數(shù)上的限制叫做單個插槽吝沫。
<!--組件的封裝者:-->
<view class="wrapper">
<view>這里是組件的內(nèi)部節(jié)點(diǎn)</view>
<!--對于不確定的內(nèi)容呻澜,可以使用<slot>進(jìn)行占位递礼,具體的內(nèi)容由組件的使用者決定-->
<slot></slot>
</view>
<!-- 組件的使用者-->
<component-tag-name>
<!--這部分內(nèi)容將被放置在組件<slot>的位置上 -->
<view>>這里是插入到組件slot中的內(nèi)容</view>
</component-tag-name>
- 多個插槽
在小程序的自定義組件中,需要使用多<slot>插槽時羹幸,可以在組件的 .js 文件中脊髓,通過如下方式進(jìn)行啟用。示例代碼如下:
Component({
//在組件定義時的選項(xiàng)中啟用多 slot 支持
options:{
multipleSlots:true
},
/**
* 組件的屬性列表
*/
properties: {
},
- 定義多個插槽
可以在組件的 .wxml中使用多個<slot>標(biāo)簽栅受,以不同的 name 來區(qū)分不同的插槽将硝。示例代碼如下:
<!--組件模板-->
<view class="wrapper">
<!--name 為 before 的第一個 slot 插槽 -->
<slot name="before"></slot>
<view>這是一段固定的文本內(nèi)容</view>
<!--name 為 after 的第二個 slot 插槽 -->
<slot name="after"></slot>
</view>
- 使用多個插槽
在使用帶有多個插槽的自定義組件時,需要用 slot 屬性來將節(jié)點(diǎn)插入到不同的<slot>中屏镊。示例代碼如下:
<!--引用組件的頁面模板-->
<component-tag-name>
<!--這部分內(nèi)容將被放置在組件<slot name="before">的位置上 -->
<view slot="before">這里是插入到組件slot name="before"中的內(nèi)容</view>
<!--這部分內(nèi)容將被放置在組件<slot name="after">的位置上 -->
<view slot="after">這里是插入到組件slot name="after"中的內(nèi)容</view>
</component-tag-name>
1.8依疼、父子組件之間的通信
父子組件之間通信的 3 種方式::
- 屬性綁定
屬性綁定用于實(shí)現(xiàn)父向子傳值,而且只能傳遞普通類型的數(shù)據(jù)而芥,無法將方法傳遞給子組件律罢。父組件的示例代碼如下:
// 父組件的 data 節(jié)點(diǎn)
data: {
count:0
}
//父組件的 wxml 結(jié)構(gòu)
<my-test3 count="{{count}}"></my-test3>
<view>---</view>
<view>父組件中,count值為:{{count}}</view>
子組件在 properties 節(jié)點(diǎn)中聲明對應(yīng)的屬性并使用棍丐。示例代碼如下:
//子組件的 properties 節(jié)點(diǎn)
properties:{
count: Number
}
//子組件的 wxml 結(jié)構(gòu)
<text>子組件中误辑,count值為:{{count}}</text>
- 事件綁定
用于子組件向父組件傳遞數(shù)據(jù),可以傳遞任意數(shù)據(jù)歌逢。使用步驟如下:
1稀余、在父組件的js 中,定義一個函數(shù)趋翻,這個函數(shù)即將通過自定義事件的形式睛琳,傳遞給子組件。
// 在父組件中定義 addCount 方法
//將來踏烙,這個方法會被傳遞給子組件师骗,供子組件進(jìn)行調(diào)用
addCount(e){
console.log(e.detail.value)
},
2、在父組件的 wxml中讨惩,通過自定義事件的形式辟癌,將步驟1中定義的函數(shù)引用,傳遞給子組件荐捻。
<component-test4 count = "4" bind:add="addCount">
<view>這是插槽內(nèi)容</view>
</component-test4>
3黍少、在子組件的js 中,通過調(diào)用 this.triggerEvent(自定義事件名稱',{/參數(shù)對象/})处面,將數(shù)據(jù)發(fā)送到父組件厂置。
methods: {
addCount(){
this.setData({
count:this.properties.count+1
}),
this.triggerEvent('add',{value:this.properties.count})
},
}
})
4、在父組件的 is 中魂角,通過 e.detail 獲取到子組件傳遞過來的數(shù)據(jù)昵济。
addCount(e){
console.log(e.detail.value)
},
獲取組件實(shí)例
父組件還可以通過 this.selectcomponent()獲取子組件實(shí)例對象這樣就可以直接訪問子組件的任意數(shù)據(jù)和方法。可在父組件里調(diào)用 this.selectComponent("id或class選擇器"),獲取子組件的實(shí)例對象访忿,從而直接訪問子組件的任意數(shù)據(jù)和方法瞧栗。調(diào)用時需要傳入一個選擇器,例如 this.selectcomponent(".my-component")海铆。
<component-test4 bind:add="addCount" class="my_component" id = "my_component">
<view>這是插槽內(nèi)容</view>
</component-test4>
<button bind:tap="getMyComponent">獲取組件實(shí)例</button>
getMyComponent(){
const child = this.selectComponent(".my_component")
child.setData({count:child.properties.count+1})
child.addCount()
},
1.9迹恐、 behaviors
behaviors 是小程序中,用于實(shí)現(xiàn)組件間代碼共享的特性卧斟,類似于 Vue.js 中的“mixins'殴边。
behaviors 的工作方式
每個 behavior 可以包含一組屬性、數(shù)據(jù)唆涝、生命周期函數(shù)和方法找都。組件引用它時,它的屬性廊酣、數(shù)據(jù)和方法會被合并到組件中能耻。
每個組件可以引用多個 behavior,behavior也可以引用其它 behavior亡驰。創(chuàng)建 behavior
調(diào)用 Behavior(0bject object)方法即可創(chuàng)建一個共享的 behavior 實(shí)例對象晓猛,供所有的組件使用:
module.exports = Behavior({
data:{
username:"tx"
},
properties:{},
methods:{}
})
- 導(dǎo)入并使用 behavior
在組件中,使用require()方法導(dǎo)入需要的 behavior凡辱,掛載后即可訪問 behavior 中的數(shù)據(jù)或方法戒职,示例代碼如下:
const myBehavior = require('../../behavior/my_behavior')
Component({
behavior:['myBehavior'],
//在組件定義時的選項(xiàng)中啟用多 slot 支持
options:{
multipleSlots:true
},
<view>在behavior中定義的數(shù)據(jù)是:{{username}}</view>
-
behavior 中所有可用的節(jié)點(diǎn)
- 同名字段的覆蓋和組合規(guī)則*
組件和它引用的 behavior 中可以包含同名的字段,此時可以參考如下3種同名時的處理規(guī)則:
同名的數(shù)據(jù)字段(data)
同名的屬性(properties)或方法(methods)
同名的生命周期函數(shù)
參考小程序官方文檔透乾。