小程序/vue中,页面onShow/mounted中执行的方法使我们发布前编写好的,那么在某些时候,我们需要动态修改onshow里执行的方法。
例如:有一个订单列表页,页面内100条订单,其中有待支付的订单,我们点击进入订单详情中,付款了这笔未付款的订单,此时返回订单列表页,是希望订单刷新的,但是如果将刷新列表的方法,直接写在页面的onshow周期中,如果用户未付款,直接返回的话,页面就会刷新,此时的这一步操作是无效的(因为订单并没有实际刷新,这次请求没有意义)。
所以,此时我们引入一个概念(待执行方法),以uni-app方法为例,我们在vuex中保存一个变量,叫onshowFunction,这样我们可以在需要插入的时候(如例子中的支付成功回调里,设置一个待执行事件),页面的onshow中,检测是否有待执行事件,如果有就执行,否则不执行,就可以动态操作onshow中的方法了。

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//store.js
const store = new Vuex.Store({
state: {
onshowFunction: {
"pages/index/index": {//仅为示例
functionName: "", //执行方法名
params: {}, //执行方法参数
path: "", //跳转路径
functionType: "", //执行类型(store/app/page,vuex方法/app/页面内方法)
pageData: "", //页面使用的特殊数据
}
},
},
mutations: {
getCurrentPages(state, options) { //检查getCurrentPages栈是否准备完成,options.num为检测页面栈中倒数num页面的route
options = options || {};
console.log("getCurrentPages")
if (getCurrentPages() && getCurrentPages()[0] && getCurrentPages()[0].route) {
if(getCurrentPages()[getCurrentPages().length - (options.num||1)]){
options.success && options.success(getCurrentPages()[getCurrentPages().length - (options.num||1)].route)
}else{
options.success && options.success()
}
} else {
setTimeout(() => {
this.commit("getCurrentPages", options)
}, 500)
}
},
setOnshowFunction(state,options){//设置待执行事件
let yuanData = state.onshowFunction[options.path];//原始数据,防止替换掉之前已经设置的数据
state.onshowFunction[options.path]={
functionName: yuanData.functionName||options.functionName||"", //执行方法名
params: yuanData.params||options.params||{}, //执行方法参数
path: yuanData.path||options.path||"", //跳转路径
functionType: yuanData.functionType||options.functionType||"", //执行类型(store/app/page,vuex方法/app/当前内方法)
pageData: yuanData.pageData||options.pageData||{}, //页面使用的特殊数据
}
options.success && options.success()
},
checkOnshowFunction(state, options) { //检测onshow中是否有待完成方法
options = options || {};
if (state.onshowFunction[options.path]) {
let {functionName,params,path,functionType} = state.onshowFunction[options.path]
if (functionName) {
new Promise((resolve)=>{
if(this.state.onLaunchData.query.needLoginYn=='Y'){
this.commit('checkLoginData',{
success:()=>{
resolve()
}
})
}else{
resolve()
}
}).then(()=>{
if (functionType == "page") {//如果保存的functionType为page,则调用的方法为页面事件,需要在页面中完成
options.success && options.success({ //成功页面需要调用next清空信息
functionName: functionName,
params: params,
next: () => {//为页面事件注入一个成功回调(执行成功后清除保存的待执行方法,保证下次onshow不会重复执行此方法)
state.onshowFunction[options.path].functionName = ""
state.onshowFunction[options.path].params = ""
state.onshowFunction[options.path].path = "";
}
});
} else {//如果保存的functionType为空,则调用的方法为全局事件,不需要在页面中完成,执行后清除储存的方法
if (functionName) {
//执行方法
this.commit(functionName, params)
//执行成功后清除保存的待执行方法,保证下次onshow不会重复执行此方法
state.onshowFunction[options.path].functionName = ""
state.onshowFunction[options.path].params = ""
} else if (path) {//如果存了个path,则onshow中执行跳转,然后清空待执行方法
this.commit("changePage", {
path: path
})
state.onshowFunction[options.path].path = "";
}
}
})
}
}
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//pages.js
onShow(){
this.$store.commit("getCurrentPages", {
success: (route) => {
this.$store.commit('checkOnshowFunction', {
path: route,
success: (res) => {//执行全局方法带来的next,清空储存数据
if (res.functionName) {
this[res.functionName](res.params)
res.next()
}
}
});
},
})
},

以上方式只是一种思路,能满足很多奇怪的需求,将onShow里的方法动态修改