将这些通信方式归类介绍:
- 组件通信
- 页面通信
- 全局通信
1.组件通信
1.properties-triggerEvent
父组件向子组件通信,与 Vue 的 props 作用相同;
子组件向父组件通信,与 Vue 的 $emit 作用相同;
父组件模板代码:
<my-component list="{{list}}" bind:customEvent="customEvent"></my-component>
父组件功能代码:
Page({
data: {
list:[]
},
customEvent(e){
console.log(e.detail.id)
}
})
子组件功能代码:
Component({
properties:{
list:{
type: Array,
value: []
}
},
attached(){
console.log(this.list);
this.triggerEvent('customEvent',{ id: 10 })
}
})
2.selectComponent
使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象,类似 Vue 的 ref;
<my-component id="mycomponent" list="{{list}}"></my-component>
Page({
onLoad(){
let mycomponent = this.selectComponent('#mycomponent')
mycomponent.setData({
list: []
})
}
})
3.selectOwnerComponent
选取当前组件节点所在的组件实例(即组件的引用者),返回它的组件实例对象,类似 Vue 的 $parent;
Component({
attached(){
let parent = this.selectOwnerComponent()
console.log(parent)
}
})
2.页面通信
1.getCurrentPages
getCurrentPages() 获取当前页面栈,数组中第一个元素为首页,最后一个元素为当前页面;
元素为一个对象,里面存放着页面的信息,包括route(页面路径)、options(onLoad拿到的参数)、method、data等;
Page({
onLoad(){
let pages = getCurrentPages()
let lastPage = pages[pages.length-2]
lastPage.setData({
list: []
})
}
})
3.全局通信
1.eventBus
通过发布订阅模式注册事件和触发事件进行通信;
使用,在app.js中进行全局实例化并挂载:
import EventBus from '/util/EventBus'
// 挂载方式一
wx.$bus = new EventBus()
App({
// 挂载方式二
eventBus: new EventBus(),
});
业务逻辑页-A:
const app = getApp()
Page({
onLoad(){
// 挂载方式一,使用
wx.$bus.on('add', this.addHandler)
// 挂载方式二,使用
app.eventBus.on('add-count', this.addHandler);
},
addHandler(a, b){
console.log(a+b)
}
})
业务逻辑页-B:
const app = getApp()
Page({
onLoad(){
// 挂载方式一,使用
wx.$bus.emit('add', 10, 20)
// 挂载方式二,使用
app.eventBus.emit('add-count');
},
})
2.globalData
将数据挂载到 app.js,这种方式在开发中很常用。通过getApp(),我们能够在任何一个页面内访问到app实例;
App({
globalData:{
list:[]
}
})
业务逻辑页:
const app = getApp()
Page({
onLoad(){
app.globalData.list.push({
id: 10
})
}
})
3.pageModel
可以在每个页面onLoad周期里面将该页面的pageModel对象缓存起来,之后在孙辈组件里面拿到祖孙的页面对象,从而触发祖孙页面对象对应的方法;
<!--第一步:实现一个pageModel,用来缓存页面对象-->
class PageModel {
constructor() {
this.pageCache = {};
}
add(page) {
let pagePath = this._getPageModelPath(page);
this.pageCache[pagePath] = page;
}
get(path) {
return this.pageCache[path];
}
delete(page) {
delete this.pageCache[this._getPageModelPath(page)];
}
<!--这一段代码是关键,存储的是__route__属性-->
_getPageModelPath(page) {
return page.__route__;
}
}
export default PageModel ;
<!--第二步:app.js中引入-->
import PageModel from './common/page-model/index.js';
App({
pageModel: new PageModel(),
});
<!--第三步:页面onLoad周期里缓存页面-->
onLoad: function(options) {
app.pageModel.add(this);
}
<!--第四步:子孙获取祖辈方法-->
methods: {
addCount() {
app.pageModel.get('pages/communicate/index').addCount();
}
}