最近使用nuxt@3.x版本做SEO优化项目比较多,之前也踩坑过,所以记录一下在 nuxt3 中路由缓存的正确使用方法,本人也之前在GitHub社区中提交过反馈问题,最后是在 3.8.2 版本解决了路由缓存问题。下面讲解如何正确使用keepalive做到页面缓存,组件缓存。

# 环境版本如下
node # 21.4.0
nuxt # 3.12.3
vue # latest 目前最新版本 3.4.*

页面缓存

keepalive 我们知道都是用来缓存组件 在组件卸载的时候 并不去真正意义上的销毁,而是隐藏掉。等再次挂载的时候再把它显示出来。其组件的状态保持原有的状态,并不会初始化。写多了 vue 项目的小伙伴们,大部分通过路由文件( src/router.js )定义 name 值,再去 router-view 组件里包裹 keepalive 组件去判断 路由里面的 name 值去使用。但是在 nuxt 框架内不需要这么复杂的操作。

  • app.vue文件内容
<!-- app.vue -->
<template>
<div>
<!-- 最新版vue支持的语法,老版本可能提示错误 -->
<NuxtPage :keepalive />
</div>
</template>
<script lang="ts" setup>
// keepalive 所需的参数 指定name值为index 的页面 进行缓存
const keepalive = {
include: ["index"],
};
</script>
  • pages文件夹
pages
├─index.vue # 若组件未定义name值 则为 文件名 index
└─user.vue # name为user
  • index.vue文件内容
<template>
<div>index</div>
<p>data: {{ data }}</p>
<p>
<button @click="data++">+1</button>
<button @click="data--">-1</button>
</p>
<p class="links">
<NuxtLink to="/user">user Page</NuxtLink>
</p>
</template>
<script setup lang="ts">
const data = ref(0);
</script>

项目启动路径为 http://localhost:3000/ 的时候,此时,在组件内操纵 data 的值变化,再去跳转 http://localhost:3000/user 时,再跳回 http://localhost:3000/data 的值不会初始化,而是切换 /user 路由前页面的状态。此时使用 onActivated api来监听组件被激活。

<script lang="ts" setup>
onActivated(() => {
console.log("onActivated 页面激活了!");
});
</script>
  • 路径复杂的请使用defineOptions指定组件name值,以免使用路由缓存失败!

例如:pages/userData.vuepages/news/detailpages/news/[id].vue。这几个路径过于复杂,在 NuxtPage 组件中难以使用 include 属性值去判断缓存条件,所以需要在页面文件中声明该页面的组件 name 值。

<!-- pages/index.vue -->
<script setup lang="ts">
defineOptions({
name: "IndexPage",
});
</script> <!-- pages/news/detail.vue -->
<script setup lang="ts">
defineOptions({
name: "newsDetail",
});
</script> <!-- app.vue -->
<template> <div>
<NuxtPage :keepalive />
</div> </template>
<script lang="ts" setup> const keepalive = {
include: ["IndexPage","newsDetail"],
// 对应 pages/index.vue ,pages/news/detail.vue 中的 name 值 缓存路由
}; </script>

组件缓存

如果在页面中,使用了v-if指令来控制组件显示,如何保证组件数据不被销毁。当然还是使用keepalive组件。假设我们在components文件中定义组件,会自动全局导入,无需引用。

components
├─Val
│ └─Input.vue # 若组件未定义name值 则为 文件名 Input
├─Counter.vue # 若组件未定义name值 则为 文件名 Counter
└─TextTip.vue # name 为 TextTip
<!-- components/Counter.vue -->
<template>
<div class="counter">
<h2>counter</h2>
<p>data:{{ data }}</p>
<p>
<button @click="data++">+1</button>
<button @click="data--">-1</button>
</p>
</div>
</template> <script lang="ts" setup>
const data = ref(0);
</script>
<style scoped>
.counter {
padding: 20px;
}
</style> <!-- components/TextTip.vue -->
<template>
<div class="text-tip">
<h2>text-tip</h2>
<p>text: {{ text }}</p>
<p>
<button @click="text += '1'">add Text</button>
</p>
</div>
</template>
<script lang="ts" setup>
const text = ref("text-1");
</script> <!-- pages/index.vue -->
<template>
<div>index</div>
<p>
<button @click="showCounter = !showCounter">
{{ !showCounter ? "显示Counter" : "显示TextTip" }}
</button>
</p>
<hr />
<KeepAlive :include="keep.include">
<Counter v-if="showCounter" />
<TextTip v-else />
</KeepAlive>
</template>
<script setup lang="ts">
const showCounter = ref(false);
const keep = {
include: ["Counter"],
};
</script>

此时点击 显示Counter 按钮,在 Counter 组件中操作内部数据改变 data:5 ,点击按钮再去切换组件显示隐藏,会发现 Counter 组件并不会销毁掉之前的值 data:5 ,而TextTip组件在操作内部的数据改变后切换 隐藏/显示 后, text 数据是初始化的值 text-1

  • 注意components文件定义的组件name值

components/Counter.vuecomponents/Val/Input.vuename 值nuxt自动会给组件的name值取为文件名 CounterInput 。而在组件自动导入的时候却是使用 <Counter /><ValInput /> 。会有点迷惑,所以请在使用 <KeepAlive> 组件包裹来缓存状态,请务必使用 defineOptions 指定组件的name值。

<!-- components/Val/Input.vue -->
<template>
<div class="input-warpper">
<h2>Input</h2>
<input v-model="val" />
</div>
</template>
<script lang="ts" setup>
const val = ref("");
defineOptions({
name: "ValInput"
})
</script>
<style>
.input-warpper {
margin: 20px;
}
</style>

或者使用 export default { name:'xxx' } 来指定组件的name值,不使用 setup 语法。

<!-- components/Val/Input.vue -->
<template>
<div class="input-warpper">
<h2>Input</h2>
<input v-model="val" />
</div>
</template>
<script lang="ts" setup>
const val = ref("");
</script>
<script lang="ts">
export default {
name: "ValInput"
}
</script>
<style>
.input-warpper {
margin: 20px;
}
</style>

案例地址

点击这里跳转代码案例,来调试 keepalive 页面缓存 和 组件缓存

推荐环境版本: node v21.4.0 , nuxt v3.12.* , 使用 pnpm 安装依赖

nuxt3正确使用keepalive页面缓存组件缓存的更多相关文章

  1. Django学习之十二:Cache 缓存组件

    目录 Django Cache 缓存组件 缓存逻辑伪代码 配置缓存源 可配置参数说明 01. Django的默认缓存 02. 基于Redis的django-redis 03. 自定义cache 04. ...

  2. Vue源码解析,keep-alive是如何实现缓存的?

    前言 在性能优化上,最常见的手段就是缓存.对需要经常访问的资源进行缓存,减少请求或者是初始化的过程,从而降低时间或内存的消耗.Vue 为我们提供了缓存组件 keep-alive,它可用于路由级别或组件 ...

  3. Vue keep-alive如何实现只缓存部分页面

    prop: include: 字符串或正则表达式.只有匹配的组件会被缓存. exclude: 字符串或正则表达式.任何匹配的组件都不会被缓存. 在2.1.0版本Vue中 常见用法: // 组件 exp ...

  4. vue 缓存的keepalive页面刷新数据

    用到这个的业务场景是这样的: a页面点击新建列表按钮进入到新建的页面b,填写b页面并点击b页面确认添加按钮,把这些数据带到a页面,填充到列表(数组),可以添加多条, 点击这条的时候进入到编辑页面,确认 ...

  5. Vue匿名组件使用keep-alive后动态清除缓存

    在使用Vue开发管理系统项目的时候,为了保存页面的浏览状态,我们可以使用内置组件keep-alive来缓存组件内部状态,避免重新渲染. <keep-alive> <router-vi ...

  6. vue-learning:34 - component - 内置组件 - 缓存组件keep-alive

    vue内置缓存组件keep-alive <keep-alive>标签内包裹的组件切换时会缓存组件实例,而不是销毁它们.避免多次加载相应的组件,减少性能消耗.并且当组件在 <keep- ...

  7. vue的组件缓存(返回页面不刷新)

    每次使用返回是页面总是会刷新 导致了一些体验上的不愉快 现在 发现vue中的一个很方便的方法还可以用来优化性能就是: keep-alive缓存组件 <router-view v-if=" ...

  8. React中实现keepalive组件缓存效果

    背景:由于react官方并没有提供缓存组件相关的api(类似vue中的keepalive),在某些场景,会使得页面交互性变的很差,比如在有搜索条件的表格页面,点击某一条数据跳转到详情页面,再返回表格页 ...

  9. keep-alive vue组件缓存避免多次加载相应的组件

    keep-alive vue组件缓存避免多次加载相应的组件

  10. vue 2.0 路由切换以及组件缓存源代码重点难点分析

    摘要 关于vue 2.0源代码分析,已经有不少文档分析功能代码段比如watcher,history,vnode等,但没有一个是分析重点难点的,没有一个是分析大命题的,比如执行router.push之后 ...

随机推荐

  1. Nifi:Nifi中的Controller Service

    Service简介 首先Nifi中的Controller Service 和我们MVC概念中的Controller Service不是一个概念,Nifi中的Controller Service更像是和 ...

  2. Js中valueOf和toString区别和使用

    对于number.string.Boolean.object.symbol数据类型调用valueOf方法,得到的都是数据本身(null.undefined两种类型上的原型链上没有valueOf方法) ...

  3. 『手撕Vue-CLI』处理不同指令

    前言 在上一篇『手撕Vue-CLI』添加自定义指令中,已经实现了自定义指令的添加,但是指令还是比较简单的,只是简单的打印一句话,那么在实际运用场景中,可能会有更多的需求,比如可能需要在指令中传递参数, ...

  4. Hugging Face ZeroGPU 计划正式发布—提供价值一千万美元的免费共享 GPU

    在人工智能技术领域,GPU 资源一直是推动研究和应用的关键因素.然而,GPU 的成本和可用性对于许多研究人员和开发者来说却是一个显著的障碍. 在 Hugging Face,我们希望人工智能技术可以更加 ...

  5. CentOS搭建Jellyfin影音服务器

    一. 安装Jellyfin 之前介绍过Docker安装jellyfin,但Docker安装方式存在一些限制,于是一起学习一下用RPM包在CentOS 7下安装方法. 先安装需要的依赖: yum ins ...

  6. 经验分享之会员 SaaS 系统

    经验分享之会员 SaaS 系统 一.前言 2018年,这是不平凡的一年:互联网行业的中台战略.会员经济等模式如火如荼,同时也逐渐地走入我们公司每个人的视野.在南海集团的战略规划背景下,当时我所在的公司 ...

  7. NumPy 二项分布生成与 Seaborn 可视化技巧

    二项分布 简介 二项分布是一种离散概率分布,用于描述在固定次数的独立试验中,事件"成功"的次数的概率分布.它通常用于分析诸如抛硬币.做选择题等具有两个结果(成功或失败)的事件. 参 ...

  8. 《剑指offer - 题目2》

    题目描述 请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy.   注意方 ...

  9. OpenCV笔记(3) CV::Mat

    1. 创建一个数组 1.1 使用构造函数 cv::Mat a; //默认构造函数 cv::Mat b = cv::Mat(); //默认构造函数 cv::Mat c = cv::Mat(3, 3, C ...

  10. 自用电脑+外网开放+SSL认证(纯免费)

    背景: 本文的目的主要是为了方便大家测试,不过有条件的情况下没必要学习了.主要是给那些没有服务器,公司也不给ssl认证的开发测试人员的一种方案:就像题目所说的那样. 纯免费,纯免费的话是有学习成本的, ...