跨页面通信

如何在小程序多个页面间调用方法传递数据?

使用 getApp()

getApp() 可以用来获取到小程序实例的全局函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// page A
Page({
data: {},
onLoad() {
// 设置到 `getApp()` 中
getApp().a = this.a.bind(this)
}
a() {
...
}
})

// page B
Page({
data: {},
b() {
...
getApp().a()
}
})...

使用 getCurrentPages() 查找对应页面对象

getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// page A
Page({
data: {},
a() {
...
}
})

// page B
Page({
data: {},
b() {
...
const pageA = getCurrentPages().filter((page) => {
return page.route == 'pages/A/index'
})[0]

if (pageA) {
pageA.a()
}
}
})...

封装

作为统一的事件广播触发机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
var broadcast = {
on: function (name, fn, isUniq) {
this._on(name, fn, isUniq, false)
},
once: function (name, fn, isUniq) {
this._on(name, fn, isUniq, true)
},
_on: function (name, fn, isUniq, once) {
var eventData
eventData = broadcast.data
var fnObj = {
fn: fn,
once: once
}
if (!isUniq && eventData.hasOwnProperty(name)) {
eventData[name].push(fnObj)
} else {
eventData[name] = [fnObj]
}
return this
},
fire: function (name, data, thisArg) {
console.log('[broadcast fire]: ' + name, data)
var fn, fnList, i, len
thisArg = thisArg || null
fnList = broadcast.data[name] || []
if (fnList.length) {
for (i = 0, len = fnList.length; i < len; i++) {
fn = fnList[i].fn
fn.apply(thisArg, [data, name])
if (fnList[i].once) {
fnList.splice(i, 1)
i--
len--
}
}
}
return this
},
data: {}
}

module.exports = broadcast

上述需求的代码就可以精简为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// page A
Page({
data: {},
onLoad() {
broadcast.on('a', this.a.bind(this))
}
a() {
...
}
})

// page B
Page({
data: {},
b() {
broadcast.fire('a')
}
})...

这样既精简了代码,也避免侵入 getApp() 对象。