InfoQ 极客传媒 15 周年庆征文|uni-app 路由传参参数丢失问题解决方案探究
一、前言
uni-app
项目开发过程中,页面间跳转的同时进行参数传递是再普通不过的应用场景。但是对于超长文本参数的传递场景,很多初级开发者并不会留意其中存在的坑。
本人在通过uni.navigateTo
进行路由跳转时,竟遇到了超长文本作为路由传递参数,目的路由页面接收参数时参数丢失,从而报 "SyntaxError: Unexpected end of JSON input"
的错误。
首先,定位报错语句:
在执行以上 JSON 解析语句时,出现以下错误信息:
报错原因:很明显,以上报错原因是由于待转换为JSON
字符串的对象不满足JSON
格式。
A 页面(原页面):
B 页面(目标页面):
通过console
控制台打印日志发现,A 页面由于传输参数过长,导致 B 页面接收的时候出现了参数丢失的现象。
注意⚠️:
url
有长度限制,太长的字符串会传递失败⚠️,可改用窗体通信postMessage
、全局变量Vuex
,另外参数中出现空格等特殊字符时需要对参数进行编码,如下为使用encodeURIComponent
对参数进行编码的示例。
上面所说的url
有长度限制,太长的字符串具体指多长呢?网上有人说是几百 K 左右,自己可以做个实验验证下。
二、解决措施
可使用窗体通信 postMessage
、页面通信uni.$emit(eventName,OBJECT)
、全局变量globalData
或者Vuex
。
2.1 应用全局变量 globalData
第一步:在App.vue
中配置全局变量:
第二步:在页面中写全局变量:
注意⚠️:在onLaunch
获取全局变量时,由于getApp
对象还未获取,暂时可以使用this.$scope.globalData
获取globalData
。
当在onLoad
获取全局变量的时候,可以通过getApp().globalData.text
直接获取。
2.2 应用全局变量 Vuex
对于熟悉Vue
的童鞋来说,状态管理工具Vuex
应该特别熟悉了。具体用法及注意事项不在此赘述,详参博文《Vue进阶(五):与 Vuex 的第一次接触》。
具体实现如下:首先定义一个store.js
公共文件
A 页面(原页面):
B 页面(目标页面):
或者通过getters
方式获取。
2.3 应用窗体通信 postMessage
注意⚠️postMessage
要通过window
对象调用!因为这里的window
不只是当前window
!大部分使用postMessage
的时候,都不是本页面的window
,而是其他网页的window
!如:
iframe
的contentWindow
;通过
window.open
方法打开新窗口的window
;window.opener
如果你使用postMessage
时没有带window
,就是用的本页面的window
来调用它。
A 页面(原页面):
B 页面(目标页面):
2.4 应用页面通信uni.$emit(eventName,OBJECT)
uni.$emit(eventName,OBJECT)
为uni-app
框架自带的页面间通信方法。
在 A 页面通过uni.$emit
触发全局的自定义事件,
在 B 页面中,通过uni.$on
监听到全局的自定义事件。
注意⚠️:使用时,注意及时销毁事件监听,比如,页面 onLoad
里边 uni.$on
注册监听,onUnload
里边 uni.$off
移除,或者一次性的事件,直接使用 uni.$once
监听。
其实,关于全局存储的方法还有很多,例如sessionStorage
,localStorage
及uni.setStorage
。这里就不再一一详述了,可详参博文《跨平台应用开发进阶(十) :uni-app 实现数据存储、获取和删除》。
三、延伸阅读 uni-app 实现内容文本置顶操作方案探究
3.1 场景再现
uni-app
项目开发过程中,需要实现文本内容置底操作(例如版权声明、免责声明等文本内容)。
刚开始自己通过position: fixed;
方式实现,对于一屏页面内容,此种样式可以实现文本内容固定于页面底部。但是,当页面内容长于屏幕高度时,就会出现文本内容悬浮于正文内容并出现遮挡的问题。
3.2 解决措施
正确的解决措施如下:
CSS
部分如下:
四、拓展阅读
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/a37f84cd9d1a86f50788d6c34】。文章转载请联系作者。
评论