欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

vue3 缓存菜单

最编程 2024-10-18 07:10:48
...

layout文件

<router-view v-slot="{ Component,route }">
            <transition name="el-fade-in-linear" mode="out-in">
              <keep-alive :include="include">
                 <component :is="formatComponentInstance(Component,route.path)" :key="route.path"/>
              </keep-alive>
            </transition>
          </router-view>



const menuTabStore = useMenuTabStore()
//缓存的组件数组 只能使用组件name
const include = computed(()=> menuTabStore.menuTabs.map(item => item.path))

//wrapperMap 缓存已经创建的组件包装器(wrapper)提高性能
let wrapperMap = new Map()
const formatComponentInstance = (component: any, path: string) => {
  let wrapper
  if (wrapperMap.has(path)) {
    wrapper = wrapperMap.get(path)
  } else {
    wrapper = {
      name: path, // 用path生成组件的name,
      render:()=> h(component)  // h的第一个参数可以是字符串,也可以是一个组件定义;h返回的是一个虚拟dom
    }
    wrapperMap.set(path, wrapper)
  }
  return h(wrapper)
}

pinan文件

import { ref } from 'vue'
import { defineStore } from 'pinia'
import router, { type Meta } from '@/router'

export interface MenuTabs {
  path: string
  meta: Meta
}

export const useMenuTabStore = defineStore(
  'menuTabStore',
  () => {
    // 菜单tabs
    const menuTabs = ref<MenuTabs[]>([])
    // 激活的tab
    const activate = ref('')

    function setMenuTabs(routes: MenuTabs[]) {
      menuTabs.value = routes
    }

    function pushMenuTab(route: any) {
        const routeCopy = {...route}
        if (!menuTabs.value.find((item) => item.path === routeCopy.path)) {
            menuTabs.value.push(routeCopy)
        }
        activate.value = route.path
    }

    function removeMenuTab(path: string) {
      const index = menuTabs.value.findIndex((item) => item.path === path)
      menuTabs.value = menuTabs.value.filter((item) => item.path !== path)
      if (activate.value === path) {
        const activateName = menuTabs.value[index]?.path || menuTabs.value[index - 1]?.path || ''
        setActivate(activateName)
      }
    }

    function setActivate(path: string) {
      if ((activate.value !== path ) && path) {
        router.push({ path })
      }
      activate.value = path
    }

    return {
      menuTabs,
      setMenuTabs,
      pushMenuTab,
      removeMenuTab,
      activate,
      setActivate
    }
  },
  {
    persist: true
  }
)