跨平台应用开发进阶(二十一) :uni-app 路由传参参数丢失问题解决方案探究_error in onload hook "syntaxerror unexpected en

56 阅读4分钟

性能优化

1.webpack打包文件体积过大?(最终打包为一个js文件)

2.如何优化webpack构建的性能

3.移动端的性能优化

4.Vue的SPA 如何优化加载速度

5.移动端300ms延迟

6.页面的重构

所有的知识点都有详细的解答,我整理成了280页PDF《前端校招面试真题精编解析》。

开源分享:docs.qq.com/doc/DSmRnRG… - 3.2 解决措施 + 四、拓展阅读

一、前言

uni-app项目开发过程中,页面间跳转的同时进行参数传递是再普通不过的应用场景。但是对于超长文本参数的传递场景,很多初级开发者并不会留意其中存在的坑。

本人在通过uni.navigateTo进行路由跳转时,竟遇到了超长文本作为路由传递参数,目的路由页面接收参数时参数丢失,从而报 "SyntaxError: Unexpected end of JSON input"的错误。

首先,定位报错语句:

this.detailData = JSON.parse(options.detailData);

在执行以上JSON解析语句时,出现以下错误信息:

[Vue warn]: Error in onLoad hook: "SyntaxError: Unexpected end of JSON input"

报错原因:很明显,以上报错原因是由于待转换为JSON字符串的对象不满足JSON格式。

A页面(原页面):

uni.navigateTo({
    url: '/pages/nextPage?detailData=' + JSON.stringify(item.detailData)
});

B页面(目标页面):

onLoad(options) {
	console.log('options.detailData', options.detailData)
	this.detailData = JSON.parse(options.detailData);
},

通过console控制台打印日志发现,A页面由于传输参数过长,导致B页面接收的时候出现了参数丢失的现象。

注意⚠️:url有长度限制,太长的字符串会传递失败⚠️,可改用窗体通信 postMessage、全局变量Vuex,另外参数中出现空格等特殊字符时需要对参数进行编码,如下为使用encodeURIComponent对参数进行编码的示例。

上面所说的url有长度限制,太长的字符串具体指多长呢?网上有人说是几百K左右,自己可以做个实验验证下。

二、解决措施

可使用窗体通信 postMessage、页面通信uni.$emit(eventName,OBJECT)、全局变量globalData或者Vuex

2.1 应用全局变量 globalData

第一步:在App.vue中配置全局变量:

<script>  
    export default {  
        globalData: {  
            text: 'text'  
        }
    }  
</script>

第二步:在页面中写全局变量:

getApp().globalData.text = 'test'

注意⚠️:在onLaunch获取全局变量时,由于getApp对象还未获取,暂时可以使用this.$scope.globalData获取globalData

当在onLoad获取全局变量的时候,可以通过getApp().globalData.text直接获取。

2.2 应用全局变量 Vuex

对于熟悉Vue的童鞋来说,状态管理工具Vuex应该特别熟悉了。具体用法及注意事项不在此赘述,详参博文《Vue进阶(五):与 Vuex 的第一次接触》。

具体实现如下:
首先定义一个store.js公共文件

// 存储数据的对象,可以将需要存储的数据在这个state中定义
const state = {
  // 当前登陆的用户名
  username: ''
}
const mutations = {
  // 提供一个方法,为state中的username赋值
  // 这些方法有一个默认的参数,这个参数就是当前store中的State
  setUserName (state, username) {
    //存入一个值
    state.username = username
  },
  getUserName (state) {
    //输出一个值
    return state.username
  }
}
//使用的时候---> 通过commit调用mutations中定义的函数,这个函数就是操作state中定义的成员的函数
// this.$store.commit('setUserName', res.data.username(请求返回的值))
const actions = {
  setUserNameAction: ({commit}, username) => {
    commit('setUserName', username)
  },
  getUserNameAction: ({commit}) => {
    commit('getUserName')
  }
}
// 通过action来触发mutations中的函数,这种触发方式是异步方式
//存入 this.$store.dispatch('setUserNameAction', res.data.username + 'aa')
//取出 this.currentUserName = this.$store.dispatch('getUserNameAction')

// Getters是从 store 中的 state 中派生出一些状态,即当出现多处需要导入某个状态时,结果不是很理想,所以getters的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
const getters = {
  getUserName: (state) => {
    return localStorage.getItem('myname')
  }
}
//使用的时候,直接使用
// <span class="welcome">你好:{{$store.getters.getUserName}}</span>

A页面(原页面):

this.$store.commit('setUserName', pageParams);

B页面(目标页面):

this.$store.state.username

或者通过getters方式获取。

this.$store.getters.userName

2.3 应用窗体通信 postMessage

window.postMessage(msg,targetOrigin)

注意⚠️postMessage要通过window对象调用!因为这里的window不只是当前window!大部分使用postMessage的时候,都不是本页面的window,而是其他网页的window!如:

  • iframecontentWindow
  • 通过window.open方法打开新窗口的window
  • window.opener

如果你使用postMessage时没有带window,就是用的本页面的window来调用它。

A页面(原页面):

window.parent.postMessage({ msg:"xxx"},'\*');

B页面(目标页面):

// 页面销毁前,务必去除监听器,否则会造成资源泄露!
beforeDestory () {
	window.removeEventListener('message', this.listenerFun)
}

mounted() {
	window.addEventListener('message',this.listenerFun)
}

methods: {
  listenerFun (e) {
	console.log(e.data);
    if(e.data.msg==='xxx'){
        // 业务处理逻辑
    }
  }
}

2.4 应用页面通信uni.$emit(eventName,OBJECT)

uni.$emit(eventName,OBJECT)uni-app框架自带的页面间通信方法。

在A页面通过uni.$emit触发全局的自定义事件,

css

1,盒模型 2,如何实现一个最大的正方形 3,一行水平居中,多行居左 4,水平垂直居中 5,两栏布局,左边固定,右边自适应,左右不重叠 6,如何实现左右等高布局 7,画三角形 8,link @import导入css 9,BFC理解

js

1,判断 js 类型的方式 2,ES5 和 ES6 分别几种方式声明变量 3,闭包的概念?优缺点? 4,浅拷贝和深拷贝 5,数组去重的方法 6,DOM 事件有哪些阶段?谈谈对事件代理的理解 7,js 执行机制、事件循环 8,介绍下 promise.all 9,async 和 await, 10,ES6 的 class 和构造函数的区别 11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式, 12,介绍一下rAF(requestAnimationFrame) 13,javascript 的垃圾回收机制讲一下, 14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】