性能优化
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!如:
iframe的contentWindow;- 通过
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,对前端性能优化有什么了解?一般都通过那几个方面去优化的?