let arr = [
{ id: 1, title: 'one' },
{ id: 2, title: 'two' },
{ id: 3, title: 'three' }
]
arr.splice(1, 1)
console.log(arr)
这时index发生了变化,列表中所有的key值都发生了变化,此时v-for会对key变化的元素重新渲染,但其实除了删除的元素其他都没有发生变化,导致vue用错误的旧子节点,做很多没有必要的工作。所以尽量不要使用index作key值,使用id等字段更好,也不要用随机数作为key,删掉旧节点,创建新节点,你的老板会被气死。
{
path: "/tips",
name: "tips",
component: resolve => require(["@/views/tips"], resolve),
meta: {
title: "路由懒加载"
}
}
关于首屏优化,过大的项目可能会因为没有加载完出现白屏的情况,可以加个loading加载提示或者启动页。
4.2 图片懒加载
<!-- 和 `` 一起使用 -->
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>
利用include、exclude属性,二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。
include属性表示只有name属性为a,b的组件会被缓存,其它组件不会被缓存,exclude属性表示除了name属性为c的组件不会被缓存,其它组件都会被缓存。
<!-- 注意是组件的名字,不是路由的名字 -->
<keep-alive include="a,b">
<router-view></router-view>
</keep-alive>
<keep-alive exclude="c">
<router-view></router-view>
</keep-alive>
mounted() {
// 在Vue组件中,可以用$on,$once去监听所有的生命周期钩子函数
// 可以通过hook监听组件销毁钩子函数,并取消监听事件
this.$once("hook:beforeDestroy", () => {
// 官方建议我们 私有property名 以$_开头
window.removeEventListener("resize", this.$_handleListen);
});
},
(2) 父子组件中
<!-- 组件的所有生命周期钩子都可以通过@hook:钩子函数名 来监听触发 -->
<component @hook:updated="$_handleListen" />
平时大多数功能不需要hook也能实现,但当第三方组件库还没有实现@change回调时,hook真的是贼香了!
<!-- 组件的所有生命周期钩
mounted() {
let arr = [1, 2, 3, 4, 5]
Object.freeze(arr)
}
当数据是滚动加载时,也是可以用concat添加数据的,合理地使用Object.freeze()可以节省很多渲染性能。
data() {
return {
serachValue: ''
};
},
watch: {
// 在值发生变化之后,重新加载数据
searchValue: {
// 通过handler来监听属性变化, 初次调用 newValue为""空字符串, oldValue为 undefined
handler(newValue, oldValue) {
if (newValue !== oldValue) {
console.log('做了一些事');
}
},
// 立即触发 如需要初始化加载数据
immediate: true,
// 深度监听 指定deep属性为true, watch会监听对象里面每一个值的变化
deep: true
}
},
// 由于函数式组件没有创建组件实例,所有传统的通过this来调用的属性,在这里都需要通过context来调用
Vue.component('my-functional-button', {
functional: true,
render: function (createElement, context) {
return createElement('button', context.data, context.children)
}
})
按需引入
使用UI框架尽量按需引入,减少多余的开销,合理的及时止损。
使用cdn的方式外部加载一些资源
module.exports = {
productionSourceMap: false,
}
官方config参考文档