<KeepAlive>
组件
缓存包裹在其中的动态切换组件
<KeepAlive>
包裹动态组件时,会缓存不活跃的组件实例,而不是销毁它们。
任何时候都只能有一个活跃组件实例作为 <KeepAlive>
的直接子节点。
完整案例:08_dynamic/02_keep-alive.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态组件</title> </head> <body> <div id="app"> <button @click="currentTab = 'Home'">首页</button> <button @click="currentTab = 'Kind'">分类</button> <button @click="currentTab = 'Cart'">购物车</button> <button @click="currentTab = 'User'">我的</button> <!-- keep-alive 保留了组件的状态,避免了组件的重新渲染 --> <keep-alive> <component :is="currentTab"></component> </keep-alive> </div> </body> <script src="../lib/vue.global.js"></script> <script> const Home = { template: ` <div> 首页 <input placeholder="首页"/> </div> ` } const Kind = { template: ` <div> 分类 <input placeholder="分类"/> </div> ` } const Cart = { template: ` <div> 购物车 <input placeholder="购物车"/> </div> ` } const User = { template: ` <div> 我的 <input placeholder="我的"/> </div> ` } Vue.createApp({ data () { return { currentTab: 'Home' } }, components: { Home, Kind, Cart, User } }).mount('#app') </script> </html>
当一个组件在 <KeepAlive>
中被切换时,它的 activated
和 deactivated
生命周期钩子将被调用,用来替代 mounted
和 unmounted
。这适用于 <KeepAlive>
的直接子节点及其所有子孙节点。
activated、deactivated钩子
完整案例:08_dynamic/02_keep-alive.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态组件</title> </head> <body> <div id="app"> <button @click="currentTab = 'Home'">首页</button> <button @click="currentTab = 'Kind'">分类</button> <button @click="currentTab = 'Cart'">购物车</button> <button @click="currentTab = 'User'">我的</button> <!-- keep-alive 保留了组件的状态,避免了组件的重新渲染 --> <keep-alive> <component :is="currentTab"></component> </keep-alive> </div> </body> <script src="../lib/vue.global.js"></script> <script> const Home = { template: ` <div> 首页 <input placeholder="首页"/> </div> `, mounted () { console.log('Home mounted') }, activated () { console.log('Home activated') }, deactivated () { console.log('Home deactivated')}, unmounted () { console.log('Home unmounted')} } const Kind = { template: ` <div> 分类 <input placeholder="分类"/> </div> `, mounted () { console.log('Kind mounted') }, activated () { console.log('Kind activated') }, deactivated () { console.log('Kind deactivated')}, unmounted () { console.log('Kind unmounted')} } const Cart = { template: ` <div> 购物车 <input placeholder="购物车"/> </div> `, mounted () { console.log('Cart mounted') }, activated () { console.log('Cart activated') }, deactivated () { console.log('Cart deactivated')}, unmounted () { console.log('Cart unmounted')} } const User = { template: ` <div> 我的 <input placeholder="我的"/> </div> `, mounted () { console.log('User mounted') }, activated () { console.log('User activated') }, deactivated () { console.log('User deactivated')}, unmounted () { console.log('User unmounted')} } Vue.createApp({ data () { return { currentTab: 'Home' } }, components: { Home, Kind, Cart, User } }).mount('#app') </script> </html>
要不不缓存,要缓存都缓存了,这样不好
使用 include
/ exclude
可以设置哪些组件被缓存,使用 max
可以设定最多缓存多少个
<!-- 用逗号分隔的字符串,中间不要家空格 --> <KeepAlive include="a,b"> <component :is="view"></component> </KeepAlive> <!-- 正则表达式 (使用 `v-bind`) --> <KeepAlive :include="/a|b/"> <component :is="view"></component> </KeepAlive> <!-- 数组 (使用 `v-bind`) --> <KeepAlive :include="['a', 'b']"> <component :is="view"></component> </KeepAlive>
组件如果想要条件性地被 KeepAlive
缓存,就必须显式声明一个 name
选项。
完整案例:08_dynamic/03_keep-alive_include.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态组件</title> </head> <body> <div id="app"> <button @click="currentTab = 'Home'">首页</button> <button @click="currentTab = 'Kind'">分类</button> <button @click="currentTab = 'Cart'">购物车</button> <button @click="currentTab = 'User'">我的</button> <!-- keep-alive 保留了组件的状态,避免了组件的重新渲染 --> <!-- <keep-alive include="ho,us"> 字符串不要加空格 --> <!-- <keep-alive :include="/ki|ca/"> 正则表达式 --> <keep-alive :include="['ho', 'ki']"> <component :is="currentTab"></component> </keep-alive> </div> </body> <script src="../lib/vue.global.js"></script> <script> const Home = { name: 'ho', template: ` <div> 首页 <input placeholder="首页"/> </div> `, mounted () { console.log('Home mounted') }, activated () { console.log('Home activated') }, deactivated () { console.log('Home deactivated')}, unmounted () { console.log('Home unmounted')} } const Kind = { name: 'ki', template: ` <div> 分类 <input placeholder="分类"/> </div> `, mounted () { console.log('Kind mounted') }, activated () { console.log('Kind activated') }, deactivated () { console.log('Kind deactivated')}, unmounted () { console.log('Kind unmounted')} } const Cart = { name: 'ca', template: ` <div> 购物车 <input placeholder="购物车"/> </div> `, mounted () { console.log('Cart mounted') }, activated () { console.log('Cart activated') }, deactivated () { console.log('Cart deactivated')}, unmounted () { console.log('Cart unmounted')} } const User = { name: 'us', template: ` <div> 我的 <input placeholder="我的"/> </div> `, mounted () { console.log('User mounted') }, activated () { console.log('User activated') }, deactivated () { console.log('User deactivated')}, unmounted () { console.log('User unmounted')} } Vue.createApp({ data () { return { currentTab: 'Home' } }, components: { Home, Kind, Cart, User } }).mount('#app') </script> </html>