vue3动态缓存页面

316 阅读2分钟

场景:管理后台的用户管理中搜索具体某个/些用户,然后点击某个用户跳转到其他页面,操作完之后又返回到用户列表页,列表页的搜索字段需要和离开时一样,当点击其他页面(例如:订单管理)再返回时又需要重新加载该页面

业务中常有一些需求需要缓存页面,但是页面一旦缓存多了又会造成性能问题,所以需要用到动态缓存页面,所谓的动态就是在需要的时候缓存页面,不需要了就踢出缓存列表。

话不多说,咱们直入主题。

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'不会被缓存

动态缓存测试.gif