Keep-alive作用及用法
定义:用来缓存组件,避免多次加载响应的组件,减少性能消耗。
用法:缓存部分页面和组件:
- 使用router.meta属性
// 这是目前用的比较多的方式
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
// 设置对应路由的keepAlive属性
routes: [
{ path: '/', redirect: '/index', component: Index, meta: { keepAlive: true }},
{
path: '/common',
component: TestParent,
children: [
{ path: '/test2', component: Test2, meta: { keepAlive: true } }
]
}
可以通过在组件内定义路由导航守卫来更改meta.keepAlive的值,来达到控制即将到达的组件页面是否缓存。
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = true;
next();
}
};
- 使用新增属性include/exclude
可以针对性缓存对应的组件。不过,这种方式需要预先知道组件的名称。
<!-- comma-delimited string -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- regex (use v-bind) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
- 动态判断
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
includedComponents动态设置即可
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。当引入keep-alive的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。
v-for加key的目的
使用v-for更新已渲染的元素列表时,默认用就地复用
策略;列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素。
vue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设:
- 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
- 同一层级的一组节点,他们可以通过唯一的id进行区分。
其实总结来说,key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
另外,v-for不加key在严格模式下会报错。
自定义指令
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// 注册一个局部指令,组将中接受一个`directives`选项
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
自定义指令中的钩子函数(均为可选):
- bind:只调用一次,指令第一次绑定到元素时,调用。在这里可以进行一次性的初始化设置。
- inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
- update: 所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。
- componentUpdated: 指令所在组件的VNode及其子VNode全部更新后调用。
- unbind: 只调用一次,指令与元素解绑时调用。
钩子函数参数:
- el: 指定所绑定的元素,可以用来直接操作DOM。
- binding: 一个包含关于绑定元素的数据对象。
- vnode: Vue编译生成的虚拟节点。
- oldVnode:上一个虚拟节点,仅在update和componentUpdated钩子中可用。
网友评论