这是我参与更文挑战的第14天,活动详情查看: 更文挑战。
前言
本文,我们聊一聊日常工作中使用 Vue.js 开发项目时的最佳实践以及风格规范。
最佳实践
为列表渲染设置属性key
key
这个特殊属性主要用在 Vue.js 的虚拟DOM算法中,在对比新旧虚拟节点时辨识虚拟节点。
我们在介绍虚拟DOM时提到,在更新子节点时,需要从旧虚拟节点列表中查找与新虚拟节点相同的节点进行更新。如果这个查找过程设置了属性key,那么查找速度会快很多。所以无论何时,建议大家尽可能地在使用 v-for 时提供key,除非遍历输出的DOM内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
在v-if/v-if-else/v-else中使用key
v-if指令在编译后是下面的样子:
(has) ? _c('li', [_v('if')]) : _c("li", [_v('else')])
所以当状态发生变化时,生成的虚拟节点既有可能是v-if上的虚拟节点,也有可能是v-else上的虚拟节点。
默认情况下,Vue.js 会尽可能高效地更新 DOM。这意味着,当它在相同类型的元素之间切换时,会修补已存在的元素,而不是将旧的元素移除,然后在同一位置添加一个新元素。如果本不相同的元素被识别为相同,则会出现意料之外的副作用。
如果添加了属性key,那么在比对虚拟 DOM 时,则会认为它们是两个不同的节点,于是会将旧元素移除并在相同的位置添加一个新元素,从而避免意料之外的副作用。
路由切换组件不变
在使用Vue.js开发项目时,最常遇到的一个典型问题就是,当页面切换到同一个路由但不同参数的地址时,组件的生命周期钩子并不会重新触发。
下面总结了3个方法来解决这个问题:
1. 路由导航守卫 beforeRouteUpdate
组件的生命周期钩子虽然不会重新触发,但是路由提供的 beforeRouteUpdate
守卫可以被触发。因此,只需要把每次切换路由时需要执行的逻辑放到 beforeRouteUpdate
守卫中即可。
2. 观察 $route对象的变化
const User = {
template: '...',
watch: {
'$route': function(to, from) {
// 对路由变化作出响应
}
}
}
3. 为router-view组件添加属性key
<router-view :key="$route.fullPath"></router-view>
为所有路由统一添加query
1. 使用全局守卫 beforeEach
2. 使用函数劫持
这种方式的原理是:通过拦截 router.history.transitionTo
方法,在 vue-router
内部在切换路由之前将参数添加到 query
中。