以下用到的代碼例子都在這裏快應用實現的微信Demo:
git clone https://github.com/yale8848/quickapp-wechat
cd quickapp-wechat
git checkout v0.1.1
爲什麼用自定義組件
自定義組件首先是一個組件,至少包含一個.ux文件,文件裏把組件要實現的UI,邏輯封裝起來共外界調用,這樣可以讓組件之間解耦,組件功能更加單一、靈活;舉個微信Demo中的一個例子,我要實現微信的titlebar功能,
當然我可以用系統的titlebar,但是爲了功能更豐富,我把它作爲一個組件來實現,下面來看看實現自定義組件的過程。
創建ux文件
如微信Demo裏的Title/index.ux,創建好<template>
,<style>
,<script>
,根據需求titlebar有3個按鈕,一個標題:
<template>
<div id="title">
<div class="left">
<image id="back" src="/Common/Image/back.png" onclick="back()"></image>
<text id="name" >{{text}}</text>
</div>
<div class="actions">
<div class="search"></div>
<div class="plus"></div>
</div>
</div>
</template>
<style>
...
</style>
<script>
export default {
back() {
router.back()
}
}
</script>
好了,上面ux文件已經把titlebar的UI創建好了,還有一個返回事件也添加了;
如何調用組件
使用improt標籤,name是自定義名稱,詳細看Demo裏的Main/index.ux
<import name="comp-title" src="../Title"></import>
<template>
<div>
<comp-title></comp-title>
</div>
</template>
這樣就可以把title調用起來了
npm run watch
npm run server
看看效果:
等等,怎麼不見標題了?嗯,咱還沒有設置呢,可能不同頁面對標題、返回按鈕是否顯示的要求不一樣,那麼我們就要能動態控制;
給子組件傳值
- 子組件用
props
屬性暴露變量給父組件調用,如下暴露['showBack', 'showText', 'showPlus', 'showSearch', 'text']
變量,它們分別是控制返回按鈕、標題、加按鈕、搜索按鈕是否顯示以及標題內容,然後把這些變量綁定到UI控件上
<script>
import router from '@system.router'
export default {
props: ['showBack', 'showText', 'showPlus', 'showSearch', 'text'],
data: {},
onInit() {},
back() {
router.back()
}
}
</script>
<template>
<div id="title">
<div class="left">
<image id="back" src="/Common/Image/back.png" show="{{showBack}}" onclick="back()"></image>
<text id="name" show="{{showText}}">{{text}}</text>
</div>
<div class="actions">
<div class="search" show="{{showSearch}}"></div>
<div class="plus" show="{{showPlus}}"></div>
</div>
</div>
</template>
- 父組件調用
通過給子組件標籤設置屬性值來調用子組件變量,子組件變量用駝峯命名方式,父組件調用子組件屬性命名用-來分隔駝峯
<import name="comp-title" src="../Title"></import>
<template>
<div>
<comp-title show-back="false" show-text="true" show-plus="true" show-search="true" text="微信"></comp-title>
</div>
</template>
調用結果如下:
父子組件通信
除過上面父組件給子組件以變量的形式傳值外,父子之間可以以消息的形式傳值:
父給子發消息
以下代碼見src/Demo/comm
子組件訂閱fatherSay消息:
```
data: {
say: ""
},
sayMsg(evt) {
this.say = evt.detail.msg //收到消息
},
onInit() {
this.$on("fatherSay", this.sayMsg) //訂閱消息
},
```
父組件給fatherSay發消息:
```
this.$broadcast('fatherSay', {
msg: "son"
})
```
子組件給父組件發消息
父組件有2種方式訂閱子組件消息:
- 父組件以js代碼形式訂閱,子組件以$dispath發送事件
onInit() {
this.$on("sonSay", this.sayMsg)
}
this.$dispath('sonSay', {
msg: t
})
- 父組件以子組件標籤屬性形式訂閱,子組件以$emit發送事件
```
<son @son-say="sayMsg"></son>
```
```
this.$emit('sonSay', {
msg: t
})
```
大家可以把manifest.json 中的entry改爲"entry": "Demo/comm"
,看看效果:
當點擊子組件say hi時父組件會收到子組件消息;
當點擊子組件say father時父組件會收到子組件消息並反饋給子組件"son"的消息
兄弟組件之間發消息
以下代碼在src/Demo/comm2中
兄弟組件之間發消息之前要先通過父組件互相綁定VM對象:
onReady() { //注意要放在onReady調用
const vm1 = this.$vm('son1')
const vm2 = this.$vm('son2')
vm1.parentVm = this
vm1.nextVm = vm2
vm2.parentVm = this
vm2.previousVm = vm1
}
然後兄弟組件之間發消息有兩種形式:
- 通過VM對象調用對方函數:
//son2.ux
brotherSay(msg) {
this.say = msg
},
//son1.ux
if (this.nextVm) {
this.nextVm.brotherSay(msg)
}
- 通過event事件:
//son1 綁定消息
events: {
eventSay(evt) {
this.say = evt.detail
}
}
//son2 通過$emit發送消息
if (this.previousVm) {
this.previousVm.$emit('eventSay', msg)
}
大家可以把manifest.json 中的entry改爲"entry": "Demo/comm2"
,看看效果:
以上用到的代碼例子都在這裏快應用實現的微信Demo:
git clone https://github.com/yale8848/quickapp-wechat
cd quickapp-wechat
git checkout v0.1.1