摘要:引入組件假如我要在里引入組件想在頁面中使用組件必須在文件里注冊組件。組件的屬性列表組件的方法列表組件內(nèi)數(shù)據(jù)傳到外部在這個組件內(nèi)我定義了這個方法,每次點擊一級菜單或二級菜單的時候我就用過方法把的值傳到組件外部以供使用。
一、前言
如果小程序中有可復(fù)用的UI且具有一定的功能性,就可以使用自定義組件將其封裝起來。(如果僅僅只需要復(fù)用UI可使用)
下面介紹父子組件的數(shù)據(jù)傳遞方法,以及一個簡單的組件和一個復(fù)雜的組件示例。
【由于剛開始寫這篇文章的時候我還算是一個小程序的新手,自己看著官方文檔研究并整理歸納的,有很多不足以及錯誤的地方。在經(jīng)過一年的沉淀以后(雖然這一年我主要在寫vue而不是小程序),我決定重新整理這篇瀏覽量比較大的文章,以免新手因我的文章走了彎路。】
二、父子組件傳遞數(shù)據(jù)的方法1.父組件向子組件傳遞數(shù)據(jù)
.wxml
.js
data: { name: "Peggy", age: 25 }
child.js
properties: { name: { type: String, value: "小明" }, age: Number }
父組件向子組件傳值以屬性的形式,子組件以接收,并可指定數(shù)據(jù)類型type以及默認值value。
在wxml里可直接以{{name}}的形式使用,而在js中以this..name獲取。
2.子組件向父組件傳值
child.js
methods: { changeName() { this.triggerEvent("changeName", { name: "李四" }) } }
.wxml
.js
changeName(event) { console.log(event.detail) // { name: "李四" } }
子組件向父組件傳遞數(shù)據(jù)使用this.方法,這個方法接受3個參數(shù):
this.("", , );
為方法名,
是傳到組件外的數(shù)據(jù),
為是否冒泡的選項微信小程序組件傳值,有三個參數(shù)可以設(shè)置:
bubbles 默認false 事件是否冒泡 composed 默認false 事件是否可以穿越組件邊界 capturePhase 默認false 事件是否擁有捕獲階段
在父組件監(jiān)聽事件="",在方法里有一個event參數(shù),可以從event.里拿到組件內(nèi)部傳出來的值。
三、簡單的組件(計數(shù)器)1. 組件功能介紹
這個組件常見于外賣軟件中,用于記錄想要購買的商品的數(shù)量。初始化的時候只有一個加號,點擊加號以后出現(xiàn)數(shù)字和減號,并最后將數(shù)字傳到組件外供外部使用。
2. 創(chuàng)建組件
首先在根目錄創(chuàng)建文件夾(推薦),然后創(chuàng)建num-文件夾(我取的組件名字),在這個文件夾上點擊右鍵新建一個,名字為index。
//num-/index.wxml
{{num}}
這段代碼就是加減兩個按鈕和一個數(shù)字。
//num-/index.json
{ "component": true, "usingComponents": {} }
這個文件在創(chuàng)建的時候會自動寫入這段代碼。
//num-/index.js
Component({ /** * 組件的屬性列表 */ properties: { nameId: { type: String }, num: { type: Number, value: 0 }, int: { type: Number, value: 1 }, min: { type: Number, value: 0 } }, /** * 組件的初始數(shù)據(jù) */ data: { }, /** * 組件的方法列表 */ methods: { numChange() { this.triggerEvent("numChange", { num: this.properties.num, nameId: this.properties.nameId }) }, add() {this.setData({ num: this.properties.num + this.properties.int }) this.numChange() }, sub() { this.setData({ num: this.properties.num - this.properties.int }) this.numChange() } } })
在組件內(nèi)部我定義了4個屬性,是父組件傳給子組件的屬性。
用來標識子組件的唯一性微信小程序組件傳值,如果在父組件內(nèi)有多個計數(shù)器,子組件想把改變的數(shù)據(jù)傳給父組件時可以用到;
num代表計數(shù)器中的數(shù)字,默認為0;
int代表加減一次改變多少,默認為1;
min代表計數(shù)器的最小值,等于這個值時減號會消失,默認為0。
同時在子組件內(nèi)定義了兩個方法:
add點擊加號觸發(fā),首先改變子組件內(nèi)部的數(shù)字,同時觸發(fā)方法將改變的數(shù)字傳到組件外部;
sub點擊減號觸發(fā),首先改變子組件內(nèi)部的數(shù)字,同時觸發(fā)方法將改變的數(shù)字傳到組件外部。
3. 引入組件
假如我要在index.wxml里引入組件:
index.json
{ "usingComponents": { "num-controller": "/components/num-controller/num-controller" } }
想在頁面中使用組件必須在json文件里注冊組件。
index.js
Page({ data: { num1: 0, num2: 10, num3: 100 }, numChange(event) { const {num, nameId} = event.detail this.setData({ [nameId]: num }) } })
data里的num1, num2, num3是從組件外傳入的num,在方法里用event.可以拿到組件內(nèi)部通過this.傳出來的數(shù)據(jù),然后根據(jù)業(yè)務(wù)需求做邏輯修改。
四、復(fù)雜的組件(篩選面板)
這是一個二級菜單,點擊左邊(一級)會改變右邊(二級)的展示。
1. 創(chuàng)建組件并引入
組件內(nèi)部:
//-panel/index.wxml
... ...
//-panel/index.json
{ "component": true, "usingComponents": {} }
組件外部:
假如我要在index.wxml里引入組件:
index.json
{ "usingComponents": { "filter-panel": "/components/filter-panel/index" } }
這樣就成功引入組件啦~(說真的組件化做好了非常舒服,后期會省很多力氣)
2.組件與外部的數(shù)據(jù)傳遞(1) 固定數(shù)據(jù)渲染
組件外部:
index.wxml
index.js
data: { list: [ ["附近", "地鐵站"], [["不限", "1km", "2km", "3km"], ["江漢路", "積玉橋", "洪山廣場", "楚河漢街", "光谷廣場"]] ], active: [0, 0] },
組件內(nèi)部:
//-panel/index.js
Component({ /** * 組件的屬性列表 */ properties: { list: Array, active: Array }, /** * 組件的方法列表 */ methods: { ...} })
如果想從組件外向組件內(nèi)傳遞數(shù)據(jù),直接在外部引用時以屬性的方式傳入。
這里我傳入了2個屬性:
list是二級選擇面板渲染的數(shù)據(jù)。
是用戶選擇的選項數(shù)據(jù)。
到這里組件已經(jīng)可以正常展示了,但是點擊顯示選中項還未實現(xiàn)。
(2) 可變數(shù)據(jù)渲染
控制組件項的是外部的數(shù)據(jù): [0, 0],通過組件以屬性的形式傳到了內(nèi)部。
//-panel/index.wxml
- {{item}}
- {{item}}
//-panel/index.js
Component({ /** * 組件的屬性列表 */ properties: { list: Array, active: Array }, /*** 組件的方法列表 */ methods: { changeLevel() { this.triggerEvent("changeLevel", { level1: this.properties.active[0], level2: this.properties.active[1] }) }, changeLevel1(event) { const index = event.target.dataset.index this.setData({ active: [index, 0] }) this.changeLevel() }, changeLevel2(event) { const level2 = "active[1]" const index = event.target.dataset.index this.setData({ [level2]: index }) this.changeLevel() } } })
(3) 組件內(nèi)數(shù)據(jù)傳到外部
在這個組件內(nèi)我定義了這個方法,每次點擊一級菜單或二級菜單的時候我就用過this.方法把的值傳到組件外部以供使用。
//-panel/index.js
methods: { changeLevel() { this.triggerEvent("changeLevel", { level1: this.properties.active[0], level2: this.properties.active[1] }) }, changeLevel1(event) { const index = event.target.dataset.index this.setData({ active: [index, 0] }) this.changeLevel() }, changeLevel2(event) { const level2 = "active[1]" const index = event.target.dataset.index this.setData({ [level2]: index }) this.changeLevel() } }
五、總結(jié)
這個項目里倒是沒用用到組件間的數(shù)據(jù)傳遞,所以只是組件和外部的傳遞,還算是比較簡單,但是一定要思考清楚數(shù)據(jù)的變化狀態(tài)。