nuxt3正确使用keepalive页面缓存组件缓存

nuxt3,keepalive · 浏览次数 : 0

小编点评

本文将介绍如何在 Nuxt.js 3.x 版本中正确使用路由缓存和组件缓存,以提高网站的性能。文章首先提到了一些常见的使用场景和解决方案,然后详细讲解了如何在 Nuxt.js 中配置路由缓存和组件缓存。 1. 路由缓存 在 Nuxt.js 中,可以使用 keep-alive 组件来实现页面缓存。在 app.vue 文件中添加 keep-alive 组件,并设置 include 属性,指定需要缓存的页面名称。 示例: ```html ``` 如果页面路径复杂,可以在页面文件中声明组件的 name 值。例如: ```html ``` 2. 组件缓存 如果需要在组件中使用 v-if 指令控制显示和隐藏,可以使用 keep-alive 组件进行缓存。在组件内部,可以通过定义 options 属性来指定组件的 name 值。 示例: ```html ``` 如果需要在多个组件中使用相同的缓存逻辑,可以在 app.vue 文件中添加 keep-alive 组件,并设置 include 属性。 示例: ```html ``` 总结:本文介绍了在 Nuxt.js 3.x 版本中如何使用 keep-alive 组件进行页面缓存和组件缓存,以提高网站的性能。通过正确配置 keep-alive 组件的 include 属性,可以实现对不同页面和组件的缓存。同时,需要注意在组件内部使用 v-if 指令控制显示和隐藏,以避免组件被销毁和重新创建。

正文

最近使用 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页面缓存组件缓存相似的内容:

nuxt3正确使用keepalive页面缓存组件缓存

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

轻松掌握useAsyncData获取异步数据

摘要:本文详细介绍Nuxt.js中的useAsyncData组合式函数,它用于在服务端渲染(SSR)过程中异步获取数据,确保客户端正确水合,避免重复请求。内容包括基本概念、参数说明(key, handler, options)、示例用法、如何监听参数变化自动刷新数据及返回值详解,展示了在页面组件中使...

Nuxt3 的生命周期和钩子函数(八)

摘要:本文介绍了Nuxt3框架中的一些重要生命周期钩子,如prepare:types用于自定义TypeScript配置和类型声明,listen用于在开发服务器启动时注册自定义事件监听器,schema:extend和schema:resolved用于扩展和处理已解析的模式,以及schema:befor...

Nuxt3 的生命周期和钩子函数(七)

摘要:文章阐述了Nuxt3中Nitro生命周期钩子的使用,如nitro:config自定义配置、nitro:init注册构建钩子、nitro:build:before/after调整构建设置及处理公共资产、prerender:routes扩展预渲染路由、build:error捕获构建错误,通过示例代...

Nuxt3 的生命周期和钩子函数(六)

摘要:本文深入解析了Nuxt3框架中的多个核心生命周期钩子和组件注册功能,包括imports:sources、imports:extend、imports:context、imports:dirs、components:dirs及components:extend,通过实例代码指导开发者如何在不同场...

Nuxt3 的生命周期和钩子函数(五)

摘要:本文详细介绍了Nuxt3中的六个核心生命周期钩子及其用法,包括build:done、build:manifest、builder:generateApp、builder:watch、pages:extend和server:devHandler:handler。内容涵盖各钩子的调用时机、参数、环...

Nuxt3 的生命周期和钩子函数(四)

概述了Nuxt3的六个关键生命周期钩子用途:modules:before至build:before,指导如何在应用初始化、模块管理、配置解析、模板处理及构建前执行自定义操作,附带实例代码,强化Nuxt应用的灵活性和可控性。

Nuxt3 的生命周期和钩子函数(三)

概述了Nuxt3的关键生命周期钩子用途,如page:finish用于页面加载后处理,page:transition:finish处理过渡效果完成,kit:compatibility扩展兼容性检查,ready标示应用启动就绪,close执行应用关闭清理,及restart控制应用重启流程,附带示例代码

Nuxt3 的生命周期和钩子函数(二)

摘要:本文深入介绍了Nuxt.js框架中几个关键的生命周期钩子函数,包括app:redirected(SSR环境下重定向前触发)、app:beforeMount(CSR下应用挂载前)、app:mounted(CSR下Vue应用在浏览器挂载时)、app:suspense:resolve(CSR中Sus...

Nuxt3 的生命周期和钩子函数(一)

摘要:本文是关于Nuxt3的系列文章之一,主要探讨Nuxt3的生命周期和钩子函数,引导读者深入了解其在前端开发中的应用。文章提供了往期相关文章链接,涉及Nuxt中间件、Composables、状态管理、路由系统、组件开发等多个方面,帮助读者全面掌握Nuxt3框架的特性和实践技巧。