uniapp全局传值方式总结(7000字长文)
uniapp的架构跟小程序一样,这样便于整体的管理和转译小程序,而uniapp的页面架构是借鉴的vue.js的单页面架构,由template(html)、script(js)、style(css)三部分组成。这样的页面架构是非常方便而独立的,不会影响到其他页面中的数据,那么问题来了,想要共享数据甚至在本页面要操控其他页面的数据怎么办?uniapp有着小程序和vue.js的有点,当然也有它们共享数据
uniapp的架构跟小程序一样,这样便于整体的管理和转译小程序,而uniapp的页面架构是借鉴的vue.js的单页面架构,由template(html)、script(js)、style(css)三部分组成。这样的页面架构是非常方便而独立的,不会影响到其他页面中的数据,那么问题来了,想要共享数据甚至在本页面要操控其他页面的数据怎么办?uniapp有着小程序和vue.js的有点,当然也有它们共享数据的方法。下面是分类说明一下uniapp的大部分传值方式,每种方式都粗略的介绍下几种方法。
全局变量globalData
小程序有一套自己的全局变量共享方法globalData,uniapp当然也要照搬过来,不然怎么号称打通所有小程序?globalData只是临时变量,在应用(小程序或者app)启动后到销毁前都是有效的,销毁后(被手机进程销毁,停止运行,有时切换到后台不会销毁,仍然在挂起运行,这取决于用户有没有给应用在后台运行的权限 [ 设置手机应用白名单 ] )globalData就没了,下次重启应用的时候globalData就恢复初始值,所以globalData是临时的。
在App.vue中配置globalData
//配置globalData
<script>
export default {
globalData: {
updateApp: {
id: null,
path: null,
},
voiceSpeed: 1.2,
voicePicth: 1,
schoolList: [],
},
onLaunch() {
this.$options.globalData.voicePicth = 2;
}
}
</script>
其他页面使用globalData
//其他页面使用globalData
var app = getApp();
export default {
onShow() {
console.log(app.globalData.voicePicth);
},
}
全局js变量工具类
会javaScript的都知道,js也是可以自定义全局变量的。js的自定义全局变量也是临时变量,销毁重建后会还原为设置的初始值,所以js全局变量跟小程序globalData的特点是一样的,只不过没有特定的写法,而globalData必须按照小程序的写法来,js全局变量由程序员自己设计。
在uniapp的common目录下新建js工具类tils.js文件
//tils.js文件
const config = {
money: "8888888",
}
function isEqual(a, b) {
return eq(a, b);
};
//暴露写法一
module.exports = {
config: config,
isEqual: isEqual
}
//暴露写法二
module.exports.config = config;
module.exports.isEqual = isEqual;
//暴露写法三
export default {
config,
isEqual,
}
//暴露写法四...写法太多太灵活了,自己去摸索吧
uniapp全局事件
见另一篇文章uniapp全局事件详解,写的非常仔细
小程序缓存
现在各家小程序大部分都是模仿鼻祖微信小程序的,不得不说张小龙这个人真的厉害,硬是带着微信做出各种带动时代的产品。微信小程序的存储机制也是很完善的,临时存储有globalData,当然也有长久性的存储缓存功能,不过是没有永久性的存储的。因为小程序再怎么牛逼,也是依赖微信app的,微信app都卸载,数据删除干净了,那么微信小程序还有什么意义呢?缓存是保存在用户手机本地的,uniapp能够跨端小程序和app等,当然也考虑了小程序的缓存功能。微信小程序的缓存只存在于微信小程序下载安装下来后到微信小程序被卸载之前的那一刻,一旦卸载或者删除了微信小程序,那么微信小程序的缓存就没有了,存在缓存里的数据当然也没有了。但是支付宝小程序不一样,支付宝小程序卸载或删除后缓存还是有的,就算清除支付宝的数据也还是有,支付宝小程序的缓存做的十分保密,但是也有缺点,就是用户删除不了缓存,如果手机遗失被黑客破解的话还是有隐患的,所以一般都不会把重要数据保存在缓存里,除非删除支付宝app,这跟微信小程序依赖微信app是同一个道理。
这里要重点说一下,不管uniapp做的怎么好怎么优秀,作为一个企业,在制作app也好,定制网站也好,都不能依靠前端,在前端是没有安全性可言的,因为能够看到的东西都是下载到了用户端本地然后被解析的,uniapp也是一款用前端技术开发app的,最好不要把用户敏感数据等重要数据保存到用户端手机本地,就算是微信小程序等也一样,虽然有的前端是有加密和防御等措施,但是也只是加深了黑客、病毒等攻击性行为的成本而已。所以在业务逻辑处过程中,如果不是那些关于用户端的系统配置数据什么的,最好都用临时数据。
缓存分为同步和异步,同步是代码按照顺序的方式执行,异步是代码在不堵塞当前执行顺序的情况下去执行另外的代码,异步与多线程、并行是不一样的,想要深入理解的还请绕道百度
//异步缓存存储数据
uni.setStorage({
key: 'name',
data: '李四',
success: function () {
console.log('success');
}
});
//异步缓存获取数据
uni.getStorage({
key: 'name',
success: function (res) {
console.log(res.data);
}
});
//异步获取当前storage的相关信息
uni.getStorageInfo({
success: function (res) {
console.log(res.keys);
console.log(res.currentSize);
console.log(res.limitSize);
}
});
//异步缓存移除数据
uni.removeStorage({
key: 'name',
success: function (res) {
console.log('success');
}
});
//异步清除所有缓存
uni.clearStorage();
===============================================================================================================================================
//同步缓存存储数据
uni.setStorageSync('name', '李四');
//同步缓存获取数据
var name = uni.getStorageSync('name');
console.log(name);
//同步获取当前storage的相关信息
const res = uni.getStorageInfoSync();
console.log(res.keys);
console.log(res.currentSize);
console.log(res.limitSize);
//同步缓存移除数据
uni.removeStorageSync('name');
//同步清除所有缓存
uni.clearStorageSync();
页面栈传值
页面栈就是从打开app第一个页面开始,就会生成一个页面记录栈,直到app关闭,用navigateTo方式会往页面栈里面添加一条 记录,用reLaunch方式会删除之前的记录后新增当前页记录,用redirectTo方式会替换跳转前那页的记录为当前页等等。通过页面栈可以方便直接的在当前页面去操控之前的那个页面的数据。
获取页面栈
//获取页面栈
var pages = getCurrentPages(); //获取页面栈,页面栈的表现形式是一个数组
var page = (pages[pages.length - 1]); //获取当前页对象
var prepage = (pages[pages.length - 2]); //获取上一页对象
...
var curRoute = page.route; //获取当前页的路由地址
...
H5操控上一个页面的数据
//H5操控上一个页面的数据
var pages = getCurrentPages();
var beforePage = pages[pages.length - 2]; //获取上一个页面对象
beforePage.orderList[2].amount = 123; //操控上一个页面的数组数据
beforePage.checkOrder(); //操控上一个页面的函数方法
app和小程序操控上一个页面的数据,需要借助$vm
//app和小程序操控上一个页面的数据
var pages = getCurrentPages();
var beforePage = pages[pages.length - 2]; //获取上一个页面对象
beforePage.$vm.orderList[2].amount = 123; //操控上一个页面的数组数据
beforePage.$vm.checkOrder(); //操控上一个页面的函数方法
app端存储数据
用存储数据的办法来共享数据是间接手段,没有直接传递数据那么直观,相当于绕个弯去传递数据。app端独有的传递数据方法有sqlite和io文件等本地存储方案。
sqlite[链接] 用于app端操作本地数据库文件,可实现数据库文件的创建,执行SQL语句等功能,相当于把服务器搭建在了用户的手机里。
io[链接] 是app端管理本地文件系统,用于对文件系统的目录浏览、文件的读取、文件的写入等操作。这就是把想要存储的数据保存为相应格式的文件(比如:txt/json/jpg/png/mp3/mp4等),然后保存到手机文件系统里,需要用到时再取出来。
H5 的存储方式
H5是前端的一部分,因为H5的出现使得前端可以在很多地方都如鱼得水,原生app可以内嵌H5页面,浏览器可以浏览H5网站。其实在uniapp中的H5指的是网页版的Html文件,因为是现在移动端的html5标准,所以简称H5。H5储数据的方案有很多,随便百度都有一堆,这里我就不班门弄斧、画蛇添足了。
vue传值方式
uniapp的页面基本架构是vue.js[链接],每个页面都是单页面结构,所以每个页面之间的数据是隔离的,组件之间也是一样。既然uniapp是按照vue.js来的,那么当然也有vue.js的大部分功能(少部分还不支持),所以要做好一个uniapp还得去学习vue.js的语法。uniapp支持以下vue.js的传值方式(下面只列出部分uniapp支持的,毕竟uniapp一直在更新升级,其他的我也没用过也不知道)。
页面传值
-
路由传值
以uni.navigateTo跳转为例,在起始页面跳转到test.vue页面并传递参数,其他跳转方式都类似
//在起始页面跳转到test.vue页面并传递参数 uni.navigateTo({ url: 'test?id=1&name=uniapp' });
在test.vue页面接受参数
//在test.vue页面接受参数 export default { onLoad(option) { //option为object类型,会序列化上个页面传递的参数 console.log(option.id); //打印出上个页面传递的参数id:1。 console.log(option.name); //打印出上个页面传递的参数name:uniapp。 } }
-
vuex全局数据管理
学完vue全家桶和微信小程序,再来写uniapp,会爽得不要不要的,因为uniapp简直就是这两者的结合体。把vuex从vue.js学的照搬到自己的uniapp中,直接撸起袖子干。第一步,在uniapp的通用js文件夹common目录中新建store.js文件
//store.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: {...}, mutations: {...}, actions: {...} }) export default store;
第二步,在入口文件main.js挂载vuex
//在main.js挂载vuex import Vue from 'vue' import App from './App' //引入vuex import store from './store' //把vuex定义成全局组件 Vue.prototype.$store = store Vue.config.productionTip = false App.mpType = 'app' const app = new Vue({ ...App, store //挂载store }) app.$mount()
第三步,在uniapp的页面里使用vuex
//页面里使用vuex <script> export default { created () { console.log(this.$store) } } </script>
vuex的数据也是临时的,想要数据持久化那就要结合缓存来做,可以参考这个例子:[链接]
-
vue页面和nvue页面通信
不多说,给个uniapp官方地址去看看吧:[链接]
组件传值
-
父子组件传值
父组件传数据到子组件,数据的传递需要借助props,是单向不可逆的
//子组件:child.vue export default { props: { //list接收父组件传过来数据 list: { type: Array, value: [] }, //或者下面的写法 list: { type: Array, default(){ return []; } }, }, methods: { getList(){ console.log(this.list) } } }; //父组件parent.vue <template> <child :list="childList"></child> </template> <script> import child from '@/components/child.vue'; export default { components: { child }, data() { return { childList:[1,2,3,5,6] } } } </script>
父组件操控子组件数据和方法
//父组件parent.vue <template> <child ref="childComponent"></child> </template> <script> import child from '@/components/child.vue'; export default { components: { child }, methods: { controlChild() { //控制子组件的方法 this.$refs.childComponent.getList(); //控制子组件的数据 this.$refs.childComponent.list[2] = 10; } } } </script>
子组件传数据给父组件,数据的传递需要借助$emit,也是单向不可逆的
//子组件:child.vue export default { methods: { getList(){ //子组件传递数据给父组件 this.$emit('changeValue', '干的漂亮'); } } }; //父组件parent.vue <template> //父组件调用子组件自定义方法changeValue来接收数据 <child @changeValue="changeChildValue"></child> </template> <script> import child from '@/components/child.vue'; export default { components: { child }, methods: { changeChildValue(event) { //event是子组件传道父组件的变量 console.log(event) //'干的漂亮' } } } </script>
-
兄弟组件传值
一、借助父组件统一管理子组件数据
二、借助vuex
三、借助globalData
四、借助全局js变量
五、借助缓存
六、太多了不扯了…
更多推荐
所有评论(0)