过去两年多一直在H5+环境里开发,刚接触uni-app不久,在h5+里可以方便的通过
WebviewObject plus.webview.create( url, id, styles, extras );
里的extras传递参数给其他页面,也可以通过
var index_main = plus.webview.getWebviewById("index_main");
index_main.evalJS('update_bill_badge_num()');
来调用已经打开的页面上的方法,或者定义一个接收参数的函数,把参数传递到已经打开的页面里
到了uni-app里的小程序,小的一些参数我可以通过/page/home/home?abc=123这种方式,或者通过LocalStoreage来传递,但是如果是比较大的json,通过第一种方式肯定不行,通过LS方式又太慢了,通过Vue.protoype.xxx来挂载一些常量还可以,变量是没用的,在这个页里修改了,在另外一个页面里还是原来的值。
我在网上看到这篇文章《微信小程序页面间通信的5种方式》https://segmentfault.com/a/1190000008895441 里的方式五:通过hack方法直接调用通信页面的方法,感觉这不就是H5+里的通过webview来传值的方式吗?
然后我就在微信小程序的开发环境里实验成功了
微信小程序里:首先定义了一个pages.js文件,在小程序根目录新建了一个plugin目录,然后放在里面
====================
pages.js的内容:
// plugin/pages.js
// 缓存pageModel,一个简要实现
export default class PM {
constructor() {
this.$$cache = {};
}
add(pageModel) {
let pagePath = this._getPageModelPath(pageModel);
this.$$cache[pagePath] = pageModel;
}
get(pagePath) {
return this.$$cache[pagePath];
}
delete(pageModel) {
try {
delete this.$$cache[this._getPageModelPath(pageModel)];
} catch (e) {
}
}
_getPageModelPath(page) {
// 关键点
return page.__route__;
}
}
====================
然后在小程序的app.js里引入:
//app.js
import PageModel from './plugin/pages.js'; //引入
App({
pages: new PageModel(), //挂载一个pages对象
onLaunch: function () {
},
globalData: {
userInfo: null
}
})
====================
在页面A里:
// pageA
let app = getApp();
Page({
data: {
helloMsg: 'hello from PageA'
},
onLoad() {
//加入页面缓存对象
app.pages.add(this);
console.log('Page A');
},
onShow(){
console.log(this.data.helloMsg);
},
gotoC() {
wx.navigateTo({
url: '/pages/home/home'
});
},
sayHello(msg) {
this.setData({
helloMsg: msg
});
},
writeHello(msg){
console.log(msg);
}
});
====================
然后在页面C里:
//pageC
let app = getApp();
Page({
onLoad(){
console.log('Page C');
this.doSomething();
},
doSomething() {
console.log('do PageC method\n\n');
// 见证奇迹的时刻
let data_msg = app.pages.get('pages/index/index').data.helloMsg;
console.log('------获取A的数据------');
console.log( data_msg );
console.log('----------------------\n\n');
console.log('------改变A的数据------');
app.pages.get('pages/index/index').sayHello('hello from PageC');
console.log('----------------------\n\n');
console.log('------调用A的方法------');
app.pages.get('pages/index/index').writeHello('PageC call PageA method!');
console.log('----------------------\n\n');
}
});
在页面C里成功获取了页面A的变量,还能调用页面A的方法,如果改变了页面A的变量,,在从页面C回到页面A时,如果显示这个被修改的变量,可以看到变量内容的确被修改了。看到这个实验的结果,我喜出望外,打算把它引入到uni-app中:
一开始我就想仿照微信小程序的方式:
====================
在main.js里
import Vue from 'vue'
import App from './App'
import store from './store'
import PageModel from './pages.js'; //引入
//省略其他内容
App.mpType = 'app'
const app = new Vue({
//加入PageModel
pages: new PageModel(),
...App
})
app.$mount()
====================
又或者放在App.vue里:
<script>
import PageModel from './pages.js';
export default {
//加入PageModel
pages: new PageModel(),
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/* 每个页面公共css */
</style>
然后在PageA里:
var app = getApp();
app.pages.add(this);
两种方法都不行,都报错误,应该是没有正确的把pages挂载到app上去。
console.log( app );
发现其实还是挂载成功了的,在很深的层里:
这样是成功的
app.$vm.$options.pages.add(this);
console.log( app.$vm.$options.pages );
在PageC里:
var page_index_obj = app.$vm.$options.pages.get('pages/index/index');
var page_index_obj_index_data = page_index_obj._data.index_data;
console.log( page_index_obj_index_data )
我对uni-app不太熟悉,对Vue也只是刚开始学习使用,然后搜到社区里一篇文章《getApp() 挂载实例方法》https://ask.dcloud.net.cn/article/35810 ,应该就是我想要的东西,但是说的太模糊了,dcloud的源码实在太长了,看不太懂,直接加到hooks也是不行的,能否指教一下,怎么把自己写的对象,挂载上去。
const hooks = [
'onHide',
'onError',
'onPageNotFound',
'onUniNViewMessage',
//'pages', //无效
];
我现在可以实现数据的传递了,但是下面这样的写法,实在是有点丑陋
app.$vm.$options.pages.add(this);
app.$vm.$options.pages.get('pages/index/index')._data.index_data;‘
另外记得在页面的onUnload里,记得要从页面栈里删除当前对象
onUnload(){
app.$vm.$options.pages.delete(this);
},
PS.我已经在项目里使用了上述方法了,相当于在app.$vm.$options.pages里建了一个栈,而且里面的数据和方法都是可以调用的,,比如关闭当前页面的时候,把本页的数据传递到上一个页面里,不知道大家还有更好的方法~
我回复了上文作者,一直没回应我,可能是太忙了,上次文章也没排版好,这次重发一遍。
2 个评论
要回复文章请先登录或注册
1***@qq.com
七分道道