一、配置路由
// params方式传递参数
{ path: '/show/:id', component: () => import('@/views/page/Show.vue'),
meta: { name: 'show' , keepAlive: true }
},
二、配置路由缓存
// !!! 重点 -- 以完整带参数的路由地址作为缓存key
// :key="route.fullPath"
// cachedComponents Strin<Array> 是存储的组件name
<router-view v-slot="{ Component }">
<keep-alive :include="cachedComponents">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</router-view>
三、使用路由卫士监听路由跳转
import { useSideStore } from '@/stores/side'
// addMenuList 调用pinia中封装的function 作用是往cachedComponents添加组件name
router.beforeEach((to, from, next) => {
const sideStore = useSideStore()
sideStore.addMenuList(to)
next()
})
pinia 处理缓存的side.js
import { defineStore } from 'pinia'
export const useSideStore = defineStore({
id: 'side',
state: () => {
return {
cachedComponents: [], // 菜单列表
openPaths: [], // 打开的页面信息
}
},
getters: {},
actions: {
// 添加菜单列表
addMenuList(item) {
const {meta, fullPath} = item
if(!this.cachedComponents.includes(meta.name) && meta.keepAlive){
this.cachedComponents.push(meta.name)
}
if(!this.openPaths.some(i => i.fullPath === fullPath)){
this.openPaths.push(item)
}
},
// 移除菜单列表
removeMenuList(item) {
const {fullPath, meta} = item
if(this.cachedComponents.includes(meta.name)){
this.cachedComponents = this.cachedComponents.filter(i => i !== meta.name)
}
if(this.openPaths.some(i => i.fullPath === fullPath)){
this.openPaths = this.openPaths.filter(i => i.fullPath !== fullPath)
}
}
},
// 开启数据缓存
persist: {
enabled: true,
strategies: [{
key: 'vite_admin_side',
storage: sessionStorage,
}]
}
})
四、使用
// 缓存测试
<el-button type="primary" @click="router.push('/show/1')">show/1</el-button>
<el-button type="primary" @click="router.push('/show/2')">show/2</el-button>
// 样式就是自己写吧
<div class="scroll-box">
<div class="tab" :class="{ 'tab-active': v.fullPath === route.fullPath}" v-for="v in openPaths" @click="handleClickTab(v)">
<span>{{ v.meta.name }}</span>
<el-icon @click="handleCloseTab(v)"><Close /></el-icon>
</div>
</div>
<router-view v-slot="{ Component }">
<keep-alive :include="cachedComponents">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</router-view>
import { ref } from 'vue'
import { storeToRefs } from "pinia"
import { useRouter} from 'vue-router'
import { useSideStore } from '@/stores/side'
import { Close } from '@element-plus/icons-vue'
const sideStore = useSideStore()
const { cachedComponents, openPaths } = storeToRefs(sideStore)
const router = useRouter()
const sideOpen = ref(false)
const menu = ref([])
const isScroll = ref(false)
const handleClick = () => {
sideOpen.value = !sideOpen.value
}
const handleClickMenu = (row) => {
router.push(`/show/${row.id}`)
}
const handleClickTab = (row) => {
router.push(row)
}
const handleCloseTab = (row) => {
sideStore.removeMenuList(row)
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。