該dome一個案例是用keep-alive實現 'form表單' 點擊跳轉 '閱讀活動協議頁' 再返回表單數據不刷新進行緩存。
另一個是keep-alive實現 '信息列表頁' 滾動到某一位置點擊跳轉'詳情頁'再返回,保留列表上次滾動到的位置。
而且用keep-alive來實現這些效果,比使用vuex或者sessionStorage這兩種方法要合理,不用重複調本地緩存,再渲染。
效果圖:
dome下載鏈接:
https://download.csdn.net/download/caimingxian401/11376624
keep-alive是vue內置的一個組件,用來對所包裹的組件進行緩存,避免返回頁面重新渲染,達到節省性能。
它實現緩存有兩種寫法:
第一種:
//在App.vue頁面
<template>
<div id="app">
<!-- $route.meta.keepAlive爲true設置緩存 -->
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<!-- $route.meta.keepAlive爲false正常顯示 -->
<router-view v-if="!$route.meta.keepAlive" />
<!-- router-view 也是一個組件,如果直接被包在 keep-alive 裏面,所有路徑匹配到的視圖組件都會被緩存 -->
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
}
}
}
</script>
//路由設置
import Vue from 'vue'
import Router from 'vue-router'
import index from './views/index'
import test from './views/test';
import pagea from './components/pageA';
import agree from './components/agree';
Vue.use(Router)
export default new Router({
//mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'index',
component: index
},
//form表單緩存頁面
{
path: '/test',
name: 'test',
component: test,
meta: {keepAlive: true}//需要緩存的頁面
},
{
path: '/pageA',
name: 'pageA1',
component: pagea
},
{
path: '/agree',
name: 'agree',
component: agree
}
]
})
//test.vue
<template>
<div class="index">
666
<!--form表單組件-->
<pageA />
</div>
</template>
<script>
import pageA from '@/components/pageA.vue';
export default {
components: {
pageA
},
data() {
return {
};
},
methods: {
},
mounted() {
console.log(this.$route.meta.keepAlive);
}
};
</script>
<style>
.index{
font-size: .12rem;
}
</style>
按照上面的流程操作,會發現第一次從首頁進入test.vue,填寫表單信息,再跳轉到'協議頁'返回,test.vue頁面信息有緩存。但是再返回首頁,再進去test.vue,會發現表單緩存仍然存在。按正常情況,首頁進入test.vue頁面,表單信息應該重新刷新,爲空。
所以我們需要在test.vue頁面再加個判斷,進入該頁面是否要清除keepalive的緩存。清除緩存參考下面的連接:
https://segmentfault.com/a/1190000015845117
在test.vue的beforeRouteLeave()事件,添加刪除keepalive緩存邏輯,如下:
beforeRouteLeave(to, from, next) {
//如果跳轉的下一頁,不是協議頁,則刪除緩存
if (to.name != "agree"){//此處判斷是如果返回上一層,你可以根據自己的業務更改此處的判斷邏輯,酌情決定是否摧毀本層緩存。
//銷燬已緩存的keepalive組件
if (this.$vnode && this.$vnode.data.keepAlive){
if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache){
if (this.$vnode.componentOptions){
var key = this.$vnode.key == null
? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '')
: this.$vnode.key;
var cache = this.$vnode.parent.componentInstance.cache;
var keys = this.$vnode.parent.componentInstance.keys;
if (cache[key]) {
if (keys.length) {
var index = keys.indexOf(key);
if (index > -1) {
keys.splice(index, 1);
}
}
delete cache[key];
}
}
}
}
this.$destroy();
}
next();
}
第二種:
另一種實現緩存的方法也需更改路由頁的寫法:
import Vue from 'vue'
import Router from 'vue-router'
import index from './views/index'
import test from './views/test';
import pagea from './components/pageA';
import agree from './components/agree';
Vue.use(Router)
export default new Router({
//mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'index',
component: index
},
{
path: '/test',
name: 'test',
component: test,
children: [ //需要執行緩存有關聯操作的頁面,都要寫在children下
{
path: '/test',
name: 'pageA1',
component: pagea,
},
{
path: '/agree',
name: 'agree',
component: agree
}
]
}
]
})
App.vue頁面不用再添加keepalive組件,改在test.vue頁面添加keepalive組件:
- include - 字符串或正則表達,只有匹配的組件會被緩存
- exclude - 字符串或正則表達式,任何匹配的組件都不會被緩存
//test.vue
<template>
<div class="index">
666
<!-- <keep-alive :include="['PageA']" > -->
<keep-alive include="PageA" >
<router-view />
</keep-alive>
<!-- name 爲 PageA 的組件將被緩存! -->
</div>
</template>
<style>
.index{
font-size: .12rem;
}
</style>
include裏面放的是組件的name,注意不是路由的name。
include裏面能寫字符串,也能用數組,正則來表達。
生命週期鉤子函數:activated、deactivated
當引入keep-alive時候,頁面進入跟離開便會觸發兩個鉤子。
activated是 進入(前進或後退) 緩存頁面時執行一次,deactivated是 離開(前進或後退) 緩存頁面時執行一次。
第一次進入頁面,鉤子執行順序:
created-> mounted-> activated
注意:第一次進入頁面時會執行一次created鉤子,但在緩存清除之前,不管頁面 離開 或 進入 都不會執行created,只執行activated或deactivated。如果清除keep-alive緩存或者刷新頁面,生命週期便會從created重新開始執行一遍。
//pageA.vue組件頁面
created () {
console.log('Created: PageA')
},
activated() {
console.log('activated: PageA')
},
deactivated() {
console.log('deactivated: PageA')
},
喜歡就留贊吧~