vue中 keep-alive的作用 和activated 和 deactivated 生命周期理解
keep-alive 简介
keep-alive
是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
用法
<keep-alive> <component> <!-- 该组件将被缓存! --> </component> </keep-alive>
props
- include - 字符串或正则表达,只有匹配的组件会被缓存
- exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
2.1.0 新增
include 和 exclude 属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:
<!-- 逗号分隔字符串 --> <keep-alive include="a,b"> <component :is="view"></component> </keep-alive> <!-- 正则表达式 (使用 `v-bind`) --> <keep-alive :include="/a|b/"> <component :is="view"></component> </keep-alive> <!-- 数组 (使用 `v-bind`) --> <keep-alive :include="['a', 'b']"> <component :is="view"></component> </keep-alive>
max
2.5.0 新增
最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
<keep-alive :max="10"> <component :is="view"></component> </keep-alive> <keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。
// 组件 a export default { name: 'a', data () { return {} } }
<keep-alive include="a"> <component> <!-- name 为 a 的组件将被缓存! --> </component> </keep-alive>可以保留它的状态或避免重新渲染 <keep-alive exclude="a"> <component> <!-- 除了 name 为 a 的组件都将被缓存! --> </component> </keep-alive>可以保留它的状态或避免重新渲染
但实际项目中,需要配合vue-router共同使用.
router-view
也是一个组件,如果直接被包在 keep-alive
里面,所有路径匹配到的视图组件都会被缓存:
<keep-alive> <router-view> <!-- 所有路径匹配到的视图组件都会被缓存! --> </router-view> </keep-alive>
如果只想 router-view
里面某个组件被缓存,怎么办?
// routes 配置 export default [ { path: '/', name: 'home', component: Home, meta: { keepAlive: true // 需要被缓存 } }, { path: '/:id', name: 'edit', component: Edit, meta: { keepAlive: false // 不需要被缓存 } } ]
<keep-alive> <router-view v-if="$route.meta.keepAlive"> <!-- 这里是会被缓存的视图组件,比如 Home! --> </router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"> <!-- 这里是不被缓存的视图组件,比如 Edit! --> </router-view>
这两个钩子需要配合配合<keep-alive><keep-alive/>
来使用
keep-alive
的作用会缓存不活动的组件实例,而不是销毁它们。当组件在<keep-alive>
内被切换,activated
和deactivated
这两个生命周期钩子函数将会被对应执行。
注意:activated,deactivated这两个生命周期函数一定是要在使用了keep-alive组件后才会有的,否则则不存在 当引入keep-alive的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。
用一个实例说明:
搭建了一个脚手架,新建2个子组件,1个父组件
子组件A内容
<template> <div> <div>componentA</div> <button @click="show=!show" >componentA事件</button> <div v-if='show'>componentA-2</div> <div v-else>componentA-1</div> </div> </template> <script> export default { name: 'componentA', comments: {}, data() { return { show: true, circle:'生命周期' } }, activated() { console.group("activated 组件激活时执行 "); }, deactivated() { console.group("deactivated 组件停用时执行"); } } </script> <style> </style>
<template> <div> <div>componentB</div> </div> </template> <script> export default { name: 'componentB', compnents: {}, data() { return {} } } </script> <style> </style>
父组件内容
<template> <div id="box"> <button @click="active='componentA'">componentA</button> <button @click="active='componentB'">componentB</button> <keep-alive> <component :is='active' ></component> </keep-alive> </div> </template> <script> import Vue from 'vue' import componentA from '@/components/componentA' import componentB from '@/components/componentB' export default{ components:{ componentA, componentB }, data(){ return{ active:'componentB' } } } </script> <style> </style>
如果如下
这里看到当A组件被点击激活时就触发activated
钩子,点击B组件开启A组件关闭时deactivated
钩子就触发执行。
这里也能看出在keep-alive
里A组件的数据也被缓存起来,第二次触发的时候组件状态没有被重新改变