需求

image.png
切换标签页后,我们想要切换前的标签页的内容不变,等我切换回来的时候可以继续使用。

比如我在A标签录入了一些文字,切到其他标签B,再切回来,这段文字还在,否则每次都让用户输入,体验不行。

实现思路

1、给vuex里储存当前打开的标签页数组tabPanes,增加一个计算属性getter
2、这个getter定义一个方法keepAliveTab,获取当前打开的标签页的key
3、页面框架,给路由标签设置标签,让vue缓存路由页面
4、 标签增加一个属性include,属性值为一个数组,数组就是keepAliveTab这个getter,在这个数组里面的标签页,才会得到缓存
5、关闭标签时,tabPanes会删掉这个标签的元素,keepAliveTab会跟着变化,这样关闭的标签就不在 标签属性include里面,就不会缓存,就会卸载Unmounted

实现

1、给vuex里储存当前打开的标签页数组tabPanes,增加一个计算属性getter
2、这个getter定义一个方法keepAliveTab,获取当前打开的标签页的key

  1. // src/store/index.js
  2. state: () => ({
  3. selectedKeyStore:"index", // 当前激活的页面的标签页、菜单
  4. tabPanes: [ // 全局的标签页,主要是配置首页不可关闭
  5. webSite.firstPage,
  6. ],
  7. }),
  8. getters: {
  9. keepAliveTab:(state)=>{ // 返还当前打开标签页的key属性,组成数组,用于动态缓存标签页
  10. let tempTab = []
  11. state.tabPanes.forEach(element => {
  12. tempTab.push(element.key)
  13. });
  14. return tempTab
  15. }
  16. }
  17. //....省略了操作tabPanes的方法

3、页面框架,给路由标签设置标签,让vue缓存路由页面
4、 标签增加一个属性include,属性值为一个数组,数组就是keepAliveTab这个getter,在这个数组里面的标签页,才会得到缓存

src/views/layout/index.vue,下面是以Vue3和ant-design-vue 2.x 为例,router-view标签内是Vue3的新写法,固定写法

  1. <template>
  2. <!-- 总框架 -->
  3. <a-layout id="baseLayout">
  4. <!-- 侧边栏 = logo + 菜单栏 -->
  5. <sidebar></sidebar>
  6. <!-- 主体内容 = 顶部栏 + 标签页 + 主页面 -->
  7. <a-layout>
  8. <!-- 顶部栏 -->
  9. <top></top>
  10. <!-- 主页面 -->
  11. <a-layout-content :style="{margin: '10px 10px',padding: '5px',background: '#fff',}">
  12. <!-- 路由页面,Vue3固定这样写 -->
  13. <router-view v-slot="{ Component }">
  14. <!-- include 是动态缓存标签页,只有当前打开的标签才会缓存,关闭则不缓存 -->
  15. <keep-alive :include="keepAlive">
  16. <component :is="Component" />
  17. </keep-alive>
  18. </router-view>
  19. </a-layout-content>
  20. </a-layout>
  21. </a-layout>
  22. </template>
  23. <script>
  24. import top from "/@/views/layout/top/index.vue"; // 引入顶部组件
  25. import sidebar from "/@/views/layout/sideBar/index.vue"; // 引入侧边栏
  26. import { computed } from "vue";
  27. import { useRouter } from "vue-router";
  28. import { useStore } from 'vuex';
  29. export default {
  30. name:"layout",
  31. components: {
  32. top, // 顶部菜单
  33. sidebar, // 菜单栏
  34. },
  35. setup() {
  36. const store = useStore()
  37. return {
  38. // 设置动态页面缓存,关闭标签页时去掉缓存
  39. keepAlive:computed(() => store.getters.keepAliveTab),
  40. };
  41. },
  42. };
  43. </script>

注意!!!

1、组件一定要有名字,否则keepAlive会失效

  1. <script>
  2. export default {
  3. name:"componentsName"
  4. }
  5. </script>

2、路由里的名字要和组件的一致,否则keepAlive会失效

  1. const routes = [
  2. {
  3. path: '/index',
  4. name: 'componentsName',
  5. component: () => import('@/views/home/index.vue'),
  6. meta: {
  7. name: "首页"
  8. },
  9. },
  10. ]