在項(xiàng)目開(kāi)發(fā)中漱贱,經(jīng)常會(huì)有一些通用的交互模塊,比如“下拉選擇列表”夭委、“搜索框”等幅狮,可能會(huì)在多個(gè)頁(yè)面中用到,直接copy株灸,paste可以在各個(gè)頁(yè)面中實(shí)現(xiàn)崇摄,但相對(duì)麻煩,而且copy的時(shí)候容易漏慌烧,也容易出現(xiàn)各種各樣的問(wèn)題逐抑,比如變量名,參數(shù)什么的屹蚊。在微信小程序中厕氨,小程序基礎(chǔ)庫(kù)提供了自定義組件的功能,開(kāi)發(fā)者可以自己把類似的交互模塊抽離成組件汹粤。
先看一波效果圖(因?yàn)槠綍r(shí)項(xiàng)目中搜索框應(yīng)用的比較多命斧,所以以搜索框的實(shí)現(xiàn)為例)
在實(shí)現(xiàn)自定義組件時(shí)我們要用到Component構(gòu)造器詳細(xì)使用方法請(qǐng)參考微信官方文檔
實(shí)現(xiàn)步驟
步驟一
在項(xiàng)目的目錄下創(chuàng)建Component(微信web開(kāi)發(fā)工具中可以右鍵直接創(chuàng)建,創(chuàng)建后在相應(yīng)的js文件中會(huì)有相應(yīng)的代碼實(shí)現(xiàn))嘱兼。
創(chuàng)建后會(huì)自動(dòng)生成js国葬,wxml,wxss芹壕,json文件汇四。
- json 文件:用于放置一些最基本的組件配置
- wxml 文件:組件模版
- wxss 文件:組件的樣式,只在組件內(nèi)部節(jié)點(diǎn)上生效(這個(gè)文件是可選的)
- js 文件:組件的 JS 代碼踢涌,承載組件的主要邏輯
在創(chuàng)建好的js文件中會(huì)默認(rèn)生成Componet構(gòu)造器通孽,具體代碼和注釋如下:
Component({
/**
* 組件的屬性列表
*/
properties: {
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
},
/**
* 組件的方法列表
*/
methods: {
}
})
具體的屬性,數(shù)據(jù)斯嚎,方法等可參照微信官方文檔利虫,一般情況下,默認(rèn)創(chuàng)建的properties堡僻,data糠惫,methods可以滿足實(shí)現(xiàn)需求,具體使用以實(shí)際情況為準(zhǔn)钉疫。
步驟二
在wxml實(shí)現(xiàn)組件硼讽,具體實(shí)現(xiàn)布局樣式及相關(guān)事件和監(jiān)聽(tīng)同一般情況下的實(shí)現(xiàn)。
- 因在實(shí)現(xiàn)時(shí)考慮到輸入框默認(rèn)提示語(yǔ)placeHolder各個(gè)界面可能會(huì)不一樣牲阁,所以將placeHolder的值定義成動(dòng)態(tài)
- 搜索框?qū)崿F(xiàn)的邏輯是當(dāng)input內(nèi)容為空時(shí)刪除按鈕隱藏固阁,input內(nèi)容不為空時(shí)刪除按鈕顯示壤躲,點(diǎn)擊刪除按鈕input內(nèi)容置空,并刪除按鈕隱藏备燃,因這些操作邏輯可以在組件內(nèi)部實(shí)現(xiàn)碉克,所以定義了相關(guān)屬性便于監(jiān)聽(tīng)和控制樣式顯示,如inputValue,hiddenClear并齐。
組件實(shí)現(xiàn)示例:
<view class='searchview'>
<icon class="iconStyle" type="search" size="25" />
<input class='inputStyle' bindinput='inputEvent' placeholder='{{initHolder}}' value='{{inputValue}}'></input>
<icon class="iconStyle" type="clear" size="25" hidden='{{hiddenClear}}' bindtap='clearEvent' />
</view>
.searchview{
width: 90%;
height: 50rpx;
display: flex;
flex-direction: row;
align-content: center;
border: 2rpx solid gainsboro;
border-radius: 10rpx;
margin: 12rpx;
padding: 12rpx;
}
.iconStyle{
color: gainsboro
}
.inputStyle{
height: 50rpx;
margin-left: 12rpx;
flex-grow: 1;
}
步驟三
js文件的實(shí)現(xiàn)漏麦。
在自定義組件時(shí),最大的實(shí)現(xiàn)區(qū)別就是JS文件的實(shí)現(xiàn)了况褪。
創(chuàng)建Component時(shí)默認(rèn)創(chuàng)建了properties撕贞,data,methods测垛。因?qū)崿F(xiàn)搜索框時(shí)暫未用到Component其他屬性捏膨,所以暫不對(duì)其他屬性做解釋和示例。
- properties
在Component構(gòu)造器中properties主要是定義wxml內(nèi)屬性的類型(type)食侮,初始值(value)号涯,執(zhí)行函數(shù)(observer)。
properties內(nèi)的屬性名是可以在外部界面引用組件時(shí)作為組件的屬性直接引用的疙描,而且屬性值是可以動(dòng)態(tài)傳遞更改的诚隙,屬性值的類型即properties中定義的type類型
微信官方示例注釋為:
properties: {
myProperty: { // 屬性名
type: String, // 類型(必填),目前接受的類型包括:String, Number, Boolean, Object, Array, null(表示任意類型)
value: '', // 屬性初始值(可選)起胰,如果未指定則會(huì)根據(jù)類型選擇一個(gè)
observer: function(newVal, oldVal){} // 屬性被改變時(shí)執(zhí)行的函數(shù)(可選)久又,也可以寫(xiě)成在methods段中定義的方法名字符串, 如:'_propertyChange'
},
myProperty2: String // 簡(jiǎn)化的定義方式
},
組件實(shí)現(xiàn)示例:
properties: {
//initHolder即在wxml布局文件中placeHolder的屬性值名稱
initHolder: {
type: String
}
},
- data
data內(nèi)容比較好理解,主要功能是提供數(shù)據(jù)進(jìn)行模板渲染效五。使用方法與一般界面實(shí)現(xiàn)相同地消。
組件實(shí)現(xiàn)示例:
data: {
inputValue: "",
hiddenClear:true //默認(rèn)隱藏刪除按鈕
},
- methods
methods中的方法可以用來(lái)包含組件的事件回調(diào)函數(shù),回調(diào)函數(shù)中可以實(shí)現(xiàn)組件內(nèi)部操作邏輯畏妖,也可以使用triggerEvent向頁(yè)面發(fā)送事件脉执,發(fā)送后在頁(yè)面中使用bind、catch就能監(jiān)聽(tīng)到戒劫。
組件實(shí)現(xiàn)示例:
methods: {
//對(duì)input組件輸入內(nèi)容進(jìn)行監(jiān)聽(tīng)
inputEvent: function (e) {
//內(nèi)容不為空時(shí)顯示刪除圖標(biāo)
if ( e.detail.value != "") {
this.setData({
hiddenClear: false
})
} else {
this.setData({
hiddenClear: true
})
}
//使用triggerEvent向頁(yè)面發(fā)送事件半夷,事件回調(diào)的內(nèi)容為e.detail
this.triggerEvent("searchViewInputEvent", e.detail)
},
//點(diǎn)擊刪除圖標(biāo)時(shí)的操作
clearEvent: function () {
this.setData({
inputValue: "",
hiddenClear: true
})
//發(fā)送事件,無(wú)內(nèi)容回調(diào)時(shí)可發(fā)送{}
this.triggerEvent("clearEvent",{})
}
}
triggerEvent方法中第一個(gè)參數(shù)定義的是回調(diào)屬性名迅细,在外部界面引用組件時(shí)只需要實(shí)現(xiàn)bind+屬性名就可以對(duì)事件進(jìn)行監(jiān)聽(tīng)巫橄。如示例代碼中 this.triggerEvent("searchViewInputEvent", e.detail) 在外部引用時(shí)引用屬性bindsearchViewInputEvent或者bind:searchViewInputEvent即可,也可以使用catch實(shí)現(xiàn)
完整示例代碼:
Component({
/**
* 組件的屬性列表
*/
properties: {
//initHolder即在wxml布局文件中placeHolder的屬性值名稱
initHolder: {
type: String
}
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
inputValue: "",
hiddenClear:true //默認(rèn)隱藏刪除按鈕
},
/**
* 組件的方法列表
*/
methods: {
//對(duì)input組件輸入內(nèi)容進(jìn)行監(jiān)聽(tīng)
inputEvent: function (e) {
//內(nèi)容不為空時(shí)顯示刪除圖標(biāo)
if ( e.detail.value != "") {
this.setData({
hiddenClear: false
})
} else {
this.setData({
hiddenClear: true
})
}
//使用triggerEvent向頁(yè)面發(fā)送事件茵典,事件回調(diào)的內(nèi)容為e.detail
this.triggerEvent("searchViewInputEvent", e.detail)
},
//點(diǎn)擊刪除圖標(biāo)時(shí)的操作
clearEvent: function () {
this.setData({
inputValue: "",
hiddenClear: true
})
//發(fā)送事件湘换,無(wú)內(nèi)容回調(diào)時(shí)可發(fā)送{}
this.triggerEvent("clearEvent",{})
}
}
})
- 在微信web開(kāi)發(fā)者工具中新建Component后生成的json文件中會(huì)默認(rèn)添加"component": true,如果不是采用新增Component方式新建的json等文件,請(qǐng)注意在json文件中添加"component": true,彩倚,添加后組件才可被引用
步驟四
上述步驟實(shí)現(xiàn)完畢后筹我,自定義組件可以在外部界面進(jìn)行引用啦。
- json文件配置帆离。
1.添加usingComponents進(jìn)行使用組件聲明蔬蕊。
2.定義組件的標(biāo)簽名,類似于<button></button>中的button的名稱定義哥谷,定義后可以對(duì)應(yīng)的wxml中通過(guò)<標(biāo)簽名></標(biāo)簽名>進(jìn)行組件的引用
3.關(guān)聯(lián)自定義組件的項(xiàng)目路徑
示例代碼:
{
"usingComponents":{
"custom-searchview":"../../components/search/common-search"
}
}
- wxml組件的引用
示例代碼:
<view>
<custom-searchview bindsearchViewInputEvent="inputLintener" bindclearEvent="clearListener" initHolder="這是一個(gè)搜索框">
</custom-searchview>
<text>{{inputValue}}</text>
</view>
- 標(biāo)簽<custom-searchview>中custom-searchview是在上述json文件中定義的標(biāo)簽名袁串。
- bindsearchViewInputEvent和bindclearEvent是在組件js文件實(shí)現(xiàn)時(shí)定義的事件名添加bind后組成的屬性名,添加bind后即可進(jìn)行綁定監(jiān)聽(tīng)
- initHolder是組件實(shí)現(xiàn)時(shí)在properties內(nèi)定義為String類型的屬性名
- inputValue只是為了方便顯示搜索框輸入時(shí)監(jiān)聽(tīng)的內(nèi)容值
- js文件的實(shí)現(xiàn)
因搜索框組件內(nèi)部已經(jīng)實(shí)現(xiàn)了簡(jiǎn)易的邏輯處理呼巷,如刪除圖標(biāo)的顯示和點(diǎn)擊后清除數(shù)據(jù)。所以頁(yè)面的js中只簡(jiǎn)單的實(shí)現(xiàn)了輸入內(nèi)容值的回調(diào)獲取赎瑰。
示例代碼:
Page({
/**
* 頁(yè)面的初始數(shù)據(jù)
*/
data: {
inputValue:""
},
/**
* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載
*/
onLoad: function (options) {
},
inputLintener:function(e){
console.log(e.detail.value)
this.setData({
inputValue: e.detail.value
})
},
clearListener:function(){
this.setData({
inputValue: ""
})
}
inputLintener:function(e)中的e值是在使用triggerEvent向界面發(fā)送數(shù)據(jù)時(shí)回調(diào)的e.detail值內(nèi)容王悍,具體參照步驟三中的methods實(shí)現(xiàn)
哈哈哈,完成后運(yùn)行即可看到上面的效果圖啦~~~