本文技术栈:vue3 + ts + pinia
相关推荐:nuxt2:keepalive 列表页到详情,详情回到列表,列表恢复离开时的状态
<KeepAlive>
是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。
keepalive组件总共有三个参数
include:可传字符串、正则表达式、数组,名称匹配成功的组件会被缓存
exclude:可传字符串、正则表达式、数组,名称匹配成功的组件不会被缓存
max:可传数字,限制缓存组件的最大数量,默认为10
include包含的 && 排除exclude包含的 就是需要缓存的组件
<keep-alive :include="" :exclude="" :max=""></keep-alive>
二、使用场景
在列表页面 点击查看 路由到详情页面
详情页面点击返回,希望回到当时从列表页面离开时的样子
(因为列表页经过了tab切换,表单查询,分页查询等操作,如果回到列表页是一个初始的状态,那么需要重新操作这一系列动作)
三、全局实现keepalive
3.1、App.vue
<template> <!-- <router-view></router-view> --> <router-view v-slot="{ Component }"> <keep-alive> <component :is="Component" /> </keep-alive> </router-view> </template> <script setup lang="ts"> onErrorCaptured(err => { console.log('Caught error', err) return false }) </script> <style scoped> </style>
3.2、src/views/keepaliva/index.vue
<template> <div class="container"> <div>keep-alive</div> <div> <el-input v-model="KValue"></el-input> </div> <div> <router-link to='/keepalive-snow'> <button>keep-aliva-snow</button> </router-link> </div> </div> </template> <script setup lang="ts"> const KValue = ref('') </script> <style scoped lang="less"> </style>
3.3、src/views/keepaliva/snow.vue
<template> <div class="container"> <div>keep-alive</div> <div> <el-input v-model="KValue"></el-input> </div> <div> <router-link to='/keepalive'> <button>keep-aliva</button> </router-link> </div> </div> </template> <script setup lang="ts"> const KValue = ref('') </script> <style scoped lang="less"> </style>
至此,简单的keepalive demo已实现。生产项目使用肯定不能这么暴力,本文继续介绍其他内容以满足生产使用。
四、router配置缓存
4.1、App.vue
<template> <!-- <router-view></router-view> --> <router-view v-slot="{ Component }"> <component :is="Component" v-if="!$route.meta.keepAlive" :key="$route.path" /> <keep-alive> <component :is="Component" v-if="$route.meta.keepAlive" :key="$route.path" /> </keep-alive> </router-view> </template> <script setup lang="ts"> onErrorCaptured(err => { console.log('Caught error', err) return false }) </script> <style scoped> .logo { height: 6em; padding: 1.5em; will-change: filter; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.vue:hover { filter: drop-shadow(0 0 2em #42b883aa); } </style>
4.2、src/routers/index.vue
{ path: '/keepalive', // keepalive component: ()=>import('../views/keepalive/index.vue'), meta: { keepAlive: true // 该页面需要keepAlive } }, { path: '/keepalive-snow', // keepalive component: ()=>import('../views/keepalive/snow.vue'), meta: { keepAlive: true // 该页面需要keepAlive } },
4.3、src/views/keepaliva/index.vue
<template> <div class="container"> <div>keep-alive</div> <div> <el-input v-model="KValue"></el-input> </div> <div> <router-link to='/keepalive-snow'> <button>keep-aliva-snow</button> </router-link> </div> </div> </template> <script setup lang="ts"> const KValue = ref('') onActivated(() => { // 调用时机为首次挂载 // 以及每次从缓存中被重新插入时 console.log('a-onActivated') }) onDeactivated(() => { // 在从 DOM 上移除、进入缓存 // 以及组件卸载时调用 console.log('a-onDeactivated') }) </script> <style scoped lang="less"> </style>
4.4、src/views/keepaliva/snow.vue
<template> <div class="container"> <div>keep-alive-snow</div> <div> <el-input v-model="KValue"></el-input> </div> <div> <router-link to='/keepalive'> <button>keep-aliva</button> </router-link> </div> </div> </template> <script setup lang="ts"> const KValue = ref('') onActivated(() => { // 调用时机为首次挂载 // 以及每次从缓存中被重新插入时 console.log('b-onActivated') }) onDeactivated(() => { // 在从 DOM 上移除、进入缓存 // 以及组件卸载时调用 console.log('b-onDeactivated') }) </script> <style scoped lang="less"> </style>
五、layouts配置keepalive--router配置
5.1、src/routers/index.vue
{ path: '/menu', // keepalive component: layout_menu, name: 'menu', children: [ { path: 'keepalive', component: ()=>import('../views/keepalive/index.vue'), name: 'keepalive', meta: { keepAlive: true // 该页面需要keepAlive } } ], meta: { keepAlive: true // 该页面需要keepAlive } }, { path: '/menu', // keepalive component: layout_menu, name: 'menu2', children: [ { path: 'keepalivesnow', component: ()=>import('../views/keepalive/snow.vue'), name: 'keepalivesnow', meta: { keepAlive: true // 该页面需要keepAlive } } ], meta: { keepAlive: true // 该页面需要keepAlive } },
5.2、layouts/menu/index.vue
<!-- src/layouts/default/index.vue --> <template> <el-container> <el-container> <el-header> <el-button @click="tomenu1">menu1</el-button> <el-button @click="tomenu2">menu2</el-button> </el-header> <el-main> <!-- 子路由出口 --> <!-- <router-view /> --> <router-view v-slot="{ Component }"> <component :is="Component" v-if="!$route.meta.keepAlive" :key="$route.path" /> <keep-alive> <component :is="Component" v-if="$route.meta.keepAlive" :key="$route.path" /> </keep-alive> </router-view> </el-main> </el-container> </el-container> </template> <script setup lang="ts"> import { useRouter } from "vue-router" const router = useRouter() const tomenu1 = ()=>{ router.push({ path: '/menu/keepalive' }) } const tomenu2 = ()=>{ console.log('28') router.push({ path: '/menu/keepalivesnow' }) } </script> <style scoped lang="less"> .el-container { height: 100vh; } .el-header { background-color: #B3C0D1; color: #ff0000; } .el-main { background-color: #E9EEF3; } </style>