场景:管理后台的用户管理中搜索具体某个/些用户,然后点击某个用户跳转到其他页面,操作完之后又返回到用户列表页,列表页的搜索字段需要和离开时一样,当点击其他页面(例如:订单管理)再返回时又需要重新加载该页面
业务中常有一些需求需要缓存页面,但是页面一旦缓存多了又会造成性能问题,所以需要用到动态缓存页面,所谓的动态就是在需要的时候缓存页面,不需要了就踢出缓存列表。
话不多说,咱们直入主题。
1. 首先创建一个vuex模块(你用pinia、mobx都行),用来保存当前已缓存的页面的名字
// ./store/keep-alive.ts
export default {
namespaced: true,
state: {
aliveList: []
},
getters: {},
mutations: {
// 添加
PUSH(state: any, payload: any) {
if (!state.aliveList.includes(payload))
state.aliveList.push(payload)
},
// 移除
REMOVE(state: any, payload: any) {
state.aliveList = state.aliveList.filter((p: any) => p !== payload)
},
// 清除全部
CLEAR(state: any) {
state.aliveList = []
}
},
actions: {}
}
2. 然后引入到你的store主文件
//.store/index.ts
import keepAlive from './keep-alive'
import {createStore} from 'vuex'
export default createStore({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {
// 缓存列表
keepAlive
}
})
3. 接着来到你的layout组件,将刚才创建的ailveList变量赋值给<keep-alive的include属性,并且在当前页面设置一个监听,如果当前页面路由的meta中设置了keepAlive为true,那么将当前页面的name放到aliveList中,如果是首页我们清空缓存列表(这个看你需不需要),关于页面的name下面我们会讲到
// Layout/index.vue
<router-view v-slot="{ Component, route }">
<keep-alive :include="store.state.keepAlive.aliveList">
<component
:is="Component"
:key="route.path"/>
</keep-alive>
</router-view>
import {useStore} from 'vuex'
const store=useStore()
// 监听新路由是否需要缓存,组件名称需要设置和路由名称相同的名字
watch(()=>route,(newVal)=>{
if(newVal.path==='/')
store.commit('keepAlive/CLEAR')
if(newVal.meta.keepAlive===true)
store.commit('keepAlive/PUSH',newVal.name)
}, { deep: true })
4.这是最后一步,也是最关键的一步,你首先要设置路由的name,再去页面中配置页面的name,两个name需要一样
//router/index.ts
{
path: 'draft',
name: 'Draft',
component: () => import('@/views/Draft/index.vue'),
meta:{
keepAlive:true
}
},
<template>
...
</template>
<script setup lang="ts">
import { onBeforeRouteLeave } from "vue-router"
import { useStore } from 'vuex'
const store = useStore()
// 离开时如果不是去详情页就不再缓存该页面
onBeforeRouteLeave((to: any, from: any, next: any) => {
const routes = ['DraftDetail']
if (!routes.includes(to.name)) {
store.commit('keepAlive/REMOVE', from.name)
}
next()
})
</script>
<script>
// 和路由名称保持一致
export default {
name: 'Draft',
}
</script>
以上就是本篇的全部内容,如有不足,欢迎指出
附上测试图片: '/draft'跳转'/fold-panel'会被缓存,但是跳到'/temporarily'不会被缓存