vue3页面缓存,使用keep-alive的include不生效

问题背景

近期项目研发vue的技术栈从vue2切换至vue3,部分写法升级。项目调试时发现页面缓存 不生效,页面使用setup语法糖(<script setup>组合式api简化写法)。定位解决过程做一个记录。

定位问题

在vue2中页面缓存使用如下

js 复制代码
//router.js 定义路由时在meta中增加cachePage配置项,将需要缓存的页面name遍历导出
const routes = [
    {
            path: '/neterror',
            component: () => import('@/views/errorPage/NetError.vue'),
            name: 'NetError',
            meta: {
                    title: '网络异常',
                    cachePage:true
            }
    }
]
let cachePages = []
for(let route of routes) {
	if(route.meta.cachePage){
		cachePage0.push(route.name)
	}
}
export const cachePage = cachePages
html 复制代码
<!-- layout.vue cachePage为需要缓存的name数组 如['NetError'],从router.js import进来 -->
<keep-alive :include="cachePage">
        <router-view />
</keep-alive>

在vue3中依样画葫芦

router还是用的js,写法一样

layout.vue里写法稍稍不一样,如下。在vue3里<transition><keep-alive>不再直接包裹<router-view><keep-alive>需要通过插槽接收动态组件

html 复制代码
<!-- 页面主体 -->
<router-view v-slot="{ Component }">
        <keep-alive :include="cachePage">
                <component :is="Component" />
        </keep-alive>
</router-view>

此时检查了cachePage的打印均无错误,但是缓存不生效。当把include去掉,缓存是有效果的。因此,定位是include引起的缓存未生效,而include只是组件名的数组,在使用setup语法糖时并未设置组件的name属性,从这里入手调试解决。

解决思路

vue2只有选项式api写法,而vue3保留了这种写法,同时增加了组合式api。在选项式api写法中,我们写组件时会显性命名。

xml 复制代码
<script> 
export default{ 
    name: 'Home' // 组件名称 
} 
</script>

而在使用setup语法糖后,无法优雅的定义组件的name值。虽然vite会根据组件的文件名自动生成组件名(文件名为 index.vue 时,组件名称会自动设置为 Index),但有时不太符合预期,如home/index.vue的name期望是Home而不是Index。

为解决此问题,装了一个插件vite-plugin-vue-setup-extend,通过<script setup name="Home">这样的方式指定组件名称,当然name需要和cachePage(即router.js中定义的路由的name)一致。(项目版本 vue:3.2.37)

sh 复制代码
#安装插件依赖
npm i vite-plugin-vue-setup-extend@0.4.0 -D
js 复制代码
//vite.config.js 引入依赖
import { defineConfig } from 'vite'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'

export default
 defineConfig({
  plugins: [ 
      VueSetupExtend() 
  ]
})
html 复制代码
<!--页面代码-->
<template>
···
</template>
<script setup name="Home">
···
</script>

vue3.3+版本也可在<script setup>使用defineOptions定义name

js 复制代码
<script setup> 
import { defineOptions } from 'vue'; 
defineOptions({ name: 'Home' }); 
</script>

总结

在vue3项目中,使用<keep-alive>缓存路由组件时,需要注意其写法,include属性使用时需注意组件名称的设置等。

相关推荐
ZC跨境爬虫2 分钟前
跟着 MDN 学 HTML day_33:(Attr 接口与属性节点的深入理解)
前端·javascript·ui·html·音视频·html5
神所夸赞的夏天16 分钟前
如何获取多层json数据,存成dictionary,并取最大最小值
java·前端·json
红色的小鳄鱼16 分钟前
前端面试js手写
开发语言·前端·javascript
焦糖玛奇朵婷20 分钟前
健身房预约小程序开发、设计
java·大数据·服务器·前端·小程序
上海云盾王帅29 分钟前
WEB业务如何接入安全防护:从零到一的实战指南
前端·安全
用户0595401744631 分钟前
AI Agent记忆丢失踩坑实录:这个问题让我排查了3天
前端·css
web行路人34 分钟前
前端对Commands(斜杠命令)一些常用
前端·javascript·vue.js·vue
当时只道寻常35 分钟前
从零到一打造企业级全栈后台管理系统 —— 技术选型、工程化实践与深度思考
前端·全栈·前端工程化
竹林81836 分钟前
用 ethers.js 连 MetaMask 做钱包登录,我踩了三个坑才搞定跨页面状态同步
前端·javascript
饺子不吃醋36 分钟前
深入理解 Vue 3 的 setup(含 Composition API)
前端·vue.js