Vue.js - 路由 vue-router 的使用详解5(keep-alive使用1:缓存组件)
<keep-alive> 是 Vue 的内置组件,它能在组件切换过程中将状态保存在内存中,防止重复渲染 DOM。下面通过样例进行演示。
一、配合组件使用
1,使用样例
(1)效果图
- 这是一个简单的 Tab 标签切换效果。当标签切换时,下方的两个自定义组件会随之切换显示。
- 由于两个子组件是包裹在 <keep-alive> 中,可以看到它们来回切换后,原来页面的内容和数据仍然保留,说明组件消失时并没有被销毁,而是缓存起来。
(2)样例代码
- 子组件1(child1.vue)
<template> <div> <h3>子页面1</h3> <input type="text" name="" value=""> </div> </template> <script> export default { name: 'child1', data() { return { } }, //keep-alive钩子函数:组件被激活时调用 activated() { console.log('子页面1被激活'); }, //keep-alive钩子函数:组件消失,被缓存时调用 deactivated() { console.log('子页面1被缓存'); } } </script>
- 子组件2(child2.vue)
<template> <div> <h3>子页面2</h3> <input type="text" name="" value=""> </div> </template> <script> export default { name: 'child2', data() { return { } }, //keep-alive钩子函数:组件被激活时调用 activated() { console.log('子页面2被激活'); }, //keep-alive钩子函数:组件消失,被缓存时调用 deactivated() { console.log('子页面2被缓存'); } } </script>
- 主页面(index.vue)
<template> <div> <div class="navi"> <div :class="{'selected':index === 1}" @click="changeIndex(1)">Tab1</div> <div :class="{'selected':index === 2}" @click="changeIndex(2)">Tab2</div> </div> <div class="container"> <keep-alive> <Child1 v-if="index === 1"> </Child1> <Child2 v-else> </Child2> </keep-alive> </div> </div> </template> <script> import Child1 from './child1.vue'; import Child2 from './child2.vue'; export default { data() { return { index: 1, //当前选中标签页索引 } }, components: { Child1, Child2, }, methods: { changeIndex(index) { this.index = index; } } } </script> <style> .navi { height: 60px; line-height: 60px; display: flex; border-bottom: 1px solid #e5e5e5; } .navi > div { flex: 1; text-align: center; } .selected { color: red; } </style>
(3)上面主页面(index.vue)的代码可以换种写法,改成动态组件,效果也是一样的。
<template> <div> <div class="navi"> <div :class="{'selected':index === 1}" @click="changeIndex(1)">Tab1</div> <div :class="{'selected':index === 2}" @click="changeIndex(2)">Tab2</div> </div> <div class="container"> <keep-alive> <component :is="currentView"></component> </keep-alive> </div> </div> </template> <script> import Child1 from './child1.vue'; import Child2 from './child2.vue'; export default { data() { return { index: 1, //当前选中标签页索引 currentView: "Child1" } }, components: { Child1, Child2, }, methods: { changeIndex(index) { this.index = index; this.currentView = "Child" + index; } } } </script> <style> .navi { height: 60px; line-height: 60px; display: flex; border-bottom: 1px solid #e5e5e5; } .navi > div { flex: 1; text-align: center; } .selected { color: red; } </style>
2,钩子函数
(1)<keep-alive> 提供了如下两个生命周期钩子函数:
(2)这两个钩子函数要注意的是:
- activated():组件被激活时调用。即组件第一次渲染时会被调用,之后每次 keep-alive 激活时也会被调用。通常我们可以在这个方法中实现:每次进入页面的时候获取最新的数据。
- deactivated():组件被停用时调用。
(2)这两个钩子函数要注意的是:
- 只有组件被 keep-alive 包裹时,这两个生命周期函数才会被调用,如果作为正常组件使用,是不会被调用的。
- 即使组件被 keep-alive 包裹,如果使用 exclude 排除之后,,这两个钩子依然不会被调用。
(3)上面样例中我们在子组件内部的钩子函数中输出了一些信息,当我们打开页面,先切换到标签 2 再切回标签 1,控制台输出如下:
3,选择性地缓存部分组件
(1)有时我们并不需要将 <keep-alive> 内的所有组件都进行缓存,<keep-alive> 提供了如下两个属性来实现这个需求:
- include:只有匹配的组件会被缓存(支持字符串或正则表达)
- exclude:任何匹配的组件都不会被缓存(支持字符串或正则表达)
(2)使用样例
- 只缓存 name 为 child1 的组件:
<keep-alive include="child1"> <component :is="currentView"></component> </keep-alive>
- 不缓存 name 为 child1 的组件:
<keep-alive exclude="child1"> <component :is="currentView"></component> </keep-alive>
- 只缓存 name 为 child1 或 child2 的组件:
<keep-alive include ="child1,child2"> <component :is="currentView"></component> </keep-alive>
- 只缓存以 child 开头的组件(使用正则表达式,需使用 v-bind):
<keep-alive :include="/^child.*/"> <component :is="currentView"></component> </keep-alive>
- 也可以动态绑定需要缓存的组件:
<keep-alive :include="includedComponents"> <component :is="currentView"></component> </keep-alive>