keep-alive 保持活躍,在vue中我們可以用其來保存組件的狀態,對組件進行緩存。
keep-alive 我們常在列表頁使用,比如我們在業務上經常會有要求,當查看完某一列表詳情頁時,返回列表頁,需要回到原來的位置,並保持頁面的狀態。
回到頁面的初始位置,我們可以在router.js中使用scrollBehavior來實現,如回到頁面頂部
scrollBehavior (to, from, savedPosition) { return { x: 0, y: 0 } }
指定位置
scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } }
言歸正傳,回到我們的keep-alive
一般情況下,組件進行切換的時候,默認會進行銷毀,如果有需求,某個組件切換后不進行銷毀,而是保存之前的狀態,那么就可以利用keep-alive來實現
舉例:兩個組件
{ path: '/cofather', name: 'cofather', component: () => import('../views/Cofather.vue') }, { path: '/compontent', name: 'compontent', component: () => import('../views/Common.vue') }
為兩個組件分別添加一個輸入框,這時我們切換組件,輸入框的值不會保存
因為在切換時組件會觸發destroyed,銷毀組件
此時我們就可以利用keep-alive組件進行包裹router-view組件,將不活動的組件緩存起來
<keep-alive> <router-view/> </keep-alive>
這時我們會發現切換組件時兩個組件輸入框的值都保存起來了
那么,我們如果只需要其中一個組件緩存,比如cofather組件緩存時,我們就需要keep-alive的兩個屬性了
- include 值為字符串或者正則表達式匹配的組件name會被緩存。
- exclude 值為字符串或正則表達式匹配的組件name不會被緩存。
注意:include 值是組件中的name命名,而不是路由中的組件name命名
<keep-alive include="cofather"> <router-view/> </keep-alive>
<template> <div> <p>父組件</p> <div style="width: 300px;margin:0 auto;"> <el-input v-model="inputval"></el-input> </div> </div> </template> <script> import api from "@/axios"; import httpConfig from "@/config/http"; export default { name: "cofather", data() { return { inputval: '' }; }, }; </script>
此時我們就會發現我們會發現cofather已經被緩存了,但是compontent沒有被緩存
而exclude就是排除了,這個就不在演示了,很簡單
除了這個我們還可以利用路由中的meta屬性來控制
{ path: '/cofather', name: 'cofather', meta:{ keepAlive:true }, component: () => import('../views/Cofather.vue') },
將cofather的路由規則中的meta添加keepAlive屬性為true,也就是當前路由組件要進行緩存
keep-alive代碼可以結合v-if進行包裹,如果meta中的keepAlive為true進行緩存,否側不進行緩存,這樣可以更靈活一些
<keep-alive> <router-view v-if="$route.meta.keepAlive" /> </keep-alive> <router-view v-if="!$route.meta.keepAlive" />
這樣組件的緩存是實現了,但是還是會有一些問題,就是因為組件被緩存,並沒有被銷毀,
所以組件在切換的時候也就不會被重新創建,自然也就不會調用created等生命周期函數,
所以此時要使用activated與deactivated來獲取當前組件是否處於活動狀態
我在cofather組件里面寫入了activated與deactivated生命周期函數
activated() { console.log("----------進activated--------"); }, deactivated() { console.log("----------進deactivated--------"); }
同時,實踐中我們可以結合路由守衛來實現需要緩存組件的緩存
beforeRouteLeave(to, from, next) { if (to.path === "/goods_detail") { from.meta.keepAlive = true; } else { from.meta.keepAlive = false; // this.$destroy() } next(); }