系列
前言
作为一名 Vue Developer,我习惯使用 Vue 组件 和 组合式 API 以及 渐进式的生态 来构建各类单页面应用(SPA),也喜欢在业余时间捣鼓开源项目和技术博客。随着项目各类需求的迭代和升级,我开始探索学习服务端渲染(SSR)和 静态站点生成(SSG)的场景和技术。
而在这探索和学习中,Nuxt 基于 Vue 的元框架,天然对 Vue 开发者的友好性,吸引了我的关注。它不仅支持多种渲染模式,集成了路由管理、状态管理、SEO优化,还提供了更丰富的生态(图层、插件、中间件、模块)以及支持多种部署环境(Github Pages、Nodejs、Cloudflare、Netlify、Vercel)
单页应用 SPA
单页应用是一种 Web 应用架构,其中应用的所有交互和内容都在一个 HTML 页面中进行,只有必要的部分才会动态加载或更新。
-
特点
- 动态加载: 页面加载后,JS 会动态加载资源,用户在切换视图时不需要重新加载
- 客户端渲染: 所有数据处理和视图渲染在客户端完成,服务器主要提供数据
- 用户体验好: 提供了流畅的用户体验,减少了页面和资源重新加载的时间
-
缺点
- SEO不友好: 由于初次加载的 HTML 页面很少或为空,搜索引擎爬虫可能无法抓取内容
- 首次加载慢: 初次加载时需要下载大量的 JavaScript 代码和资源
服务端渲染 SSR
服务端渲染(Server-Side Rendering)是在服务器端生成完整的 HTML 页面,然后将这些页面发送到客户端。
-
特点
- 预渲染页面: 页面在服务器端生成并发送到客户端,提升了首屏加载速度
- SEO较友好: 服务器生成完整页面,搜索引擎爬虫可以轻松抓取内容,利于SEO
- 动态内容: 支持动态内容的生成,适合需要根据用户请求动态生成页面的应用
-
缺点
- 服务器负担: 需要在服务器端处理每个请求,可能会增加服务器的负担
- 较慢的交互: 虽然首屏加载快,但后续的用户交互仍然需要客户端 JS 处理
静态站点生成 SSG
静态站点生成是在构建时生成所有页面的静态 HTML 文件,这些文件在用户请求时直接提供。
-
特点
- SEO较友好: 生成的静态 HTML 页面对搜索引擎友好
- 加载速度快: 由于页面已经预先生成并缓存,用户访问时只需获取静态文件,加载速度非常快
- 服务器负担低: 服务器只需提供静态文件,减少了计算和处理需求
-
缺点
- 不适合频繁变动: 如果内容频繁更新,可能需要重新生成整个站点或使用增量生成技术
- 动态功能限制: 对于需要实时动态生成内容的应用,静态站点可能不适合
初识 Nuxt
概述简介
Nuxt 是一个基于 Vue 的元框架,专注于构建现代化的 Web 应用。它提供了一系列功能和工具,旨在简化开发过程,提高应用性能,并支持多种渲染模式。无论是服务端渲染、静态站点生成、还是单页面应用都能提供出色的支持,并具有如下特点:
-
支持渲染模式
- 支持服务端渲染 (SSR): 适用合需要快速首屏加载和搜索引擎优化的场景
- 静态站点生成 (SSG): 适用内容变化不频繁的应用,提高加载速度,减少服务器负担
- 客户端渲染 (SPA): 开发者可以构建传统的 Vue 单页面应用
-
自动化和约定
- 自动导入: 在约定的目录中编写 Vue 可组合项和组件并使用它们,而无需导入它们
- 基于文件的路由: 通过
pages
目录中文件和文件夹自动生成。无需要手动配置路由文件 - 自带服务器端渲染: Nuxt 带有内置的 SSR 功能,因此您无需自己设置单独的服务器
- 零配置 TypeScript: 自动生成的类型编写类型安全的代码,提高代码可维护性和效率
- 配置的构建工具: 默认使用
Vite
来支持开发中的热模块替换 (HMR) 和 构建生产内容 - 运行时配置: 允许应用运行期间动态设置和调整配置选项,如环境变量、API 路径等
-
丰富的生态
- 图层(Layers): 用于从 git 存储库或 npm 包中共享和重复使用部分 Nuxt 应用程序
- 插件(Plugins): 用于扩展和自定义应用 Vue 实例功能以及服务端 Nitro 引擎的扩展
- 中间件(Middleware): 用于对请求和响应进行自定义处理(身份验证、日志/错误处理)
- 模块(Modules): 用于引入第三方模块(例 pinia),使用第三方模块的组件或插件等功能
-
支持部署环境
-
静态站点托管:
Nuxt 静态站点生成功能可以将整个应用预渲染为静态 HTML 文件,部署在任何支持静态文件托管的服务上。例 GitHub Pages、Vercel、Netlify、或 Nginx 服务代理如 Vue 单页面应用,通常就属于静态站点托管,一般是 nginx 代理访问。
-
Node 服务端托管:
Nuxt 可以通过服务器端渲染模式生成动态内容,这种方式需要一个支持 Node 环境的服务器,例如 通过 PM2 启动服务,或者第三方平台 AWS、Google Cloud Platform 等 -
边缘计算和无服务器架构:
通过无服务器架构或边缘计算,Nuxt 可以在全球范围内快速提供内容,减少延迟。例如 Vercel、Netlify Functions、Cloudflare Workers
-
应用场景
-
企业级应用
企业级应用通常需要高性能、可扩展和可维护的解决方案。Nuxt 的服务端渲染功能可以提高应用的首屏加载速度和 SEO 性能,同时也可以支持复杂的业务逻辑和大规模的应用结构。例: 公司官网、企业门户网站、内部管理系统、客户管理系统
-
内容管理系统
内容管理系统需要高效的内容发布和管理功能。Nuxt 的静态站点生成功能适合生成静态的内容页面,提高加载速度和减少服务器负担。例: 博客、新闻网站、技术文档网站
(由 @nuxt/content 模块实现)
-
电子商务网站
电子商务网站需要快速的页面加载速度和良好的用户体验。Nuxt 可以通过 SSR 提高页面加载性能,并通过静态生成技术预渲染产品页面以提高访问速度。例: 在线商店、产品目录、电子商务平台
-
......
关键概念
在不断学习 Nuxt 旅途中,了解了 Nuxt 通过 图层(Layers)、插件(Plugins)、中间件(Middleware)、模块(Modules)等概念,为开发者提供了一个高度灵活和可扩展的开发环境,所以就图层、插件、中间件、模块、服务端渲染、以及运行时配置,做进一步说明和讲解。
图层 Layers
图层是一个包含 Nuxt 配置、模块和其他资源的目录。每个图层可以包含自己的 nuxt.config.js
配置文件、模块、插件等。这种结构使得不同的图层可以独立开发和管理。
components/*
扩展默认组件composables/*
扩展默认可组合项layouts/*
扩展默认布局pages/*
扩展默认页面plugins/*
扩展默认插件server/*
扩展默认服务器端点和中间件utils/*
扩展默认实用程序nuxt.config.ts
扩展默认 nuxt 配置app.config.ts
扩展默认应用配置
具有如下作用
- 通过将应用拆分为多个图层,可以实现更好的模块化,每个图层专注于应用的一个特定方面。
- 图层之间可以继承和覆盖配置,使得共享配置可以集中管理,同时允许对特定图层定制化设置。
- 通过图层可以在多个项目中复用相同模块和配置,提高开发效率和一致性,图层可以是 npm 包
其他说明
- 图层内文件将被 Nuxt 自动扫描并在项目中使用,而无需手到导入。
- 这意味着,图层内的目录和文件等同于你在项目的手动编写开发一样。
- 当然就近原则,项目中同名组件、布局、页面等覆盖于图层中同名文件内容。
- 如果以 JavaScript 的作用域中变量去理解项目所引用的图层内容,还挺 "适用"。
- 每个 Nuxt 项目都可以视为图层,并根据需要加载不同图层,也可以被其他图层加载
应用场景
- 多主题支持:
通过图层,你可以为应用创建多个主题,每个主题作为一个独立的图层,并根据用户的选择或配置动态加载不同的主题图层。 - 多租户应用:
在多租户应用中,不同租户可能需要不同的配置或功能。你可以为每个租户创建一个图层,这些图层可以包含特定的路由、组件和服务端逻辑。 - 插件系统:
开发一个可扩展的插件系统,每个插件作为一个独立的图层,实现特定功能,如身份验证、支付集成、数据分析等。 - 渐进式迁移:
如果你正在将一个大型遗留项目迁移到 Nuxt,可以将不同的部分逐步迁移到图层中,确保平稳过渡。
参考文档
插件 Plugins
Nuxt 插件是一个功能强大的机制,它允许开发者在 Vue 应用初始化时执行自定义代码,以扩展或定制应用的行为,如果是服务端插件则允许开发者配置身份验证和授权、数据上的预处理以及处理请求拦截、重定向、日志记录等功能。
Nuxt 插件是分 客户端插件 和 服务端插件 两类:
-
客户端插件 (Nuxt4 目录结构: ~/app/plugins/xxx.ts)
// 例. 全局注册 Ant Design Vue 组件 import Antd from 'ant-design-vue' export default defineNuxtPlugin((nuxtApp) => { nuxtApp.vueApp.use(Antd) })
// 例. 全局注册指令 export default defineNuxtPlugin((nuxtApp) => { nuxtApp.vueApp.directive('action', { mounted (el) { //... }, }) })
-
服务端插件 (Nuxt4 目录结构: ~/server/plugins/xxx.ts)
// 例. 返回 html 页面时,注入 <meta> 信息 export default defineNitroPlugin((nitroApp) => { nitroApp.hooks.hook('render:html', (html) => { html.head.push('<meta name="viewport" content="width=device-width, initial-scale=1">') }) })
Nitro Plugin 文档:nitro.unjs.io/guide/plugi…
中间件 Middleware
在 Nuxt 框架中,中间件也分 客户端路由中间件 和 服务端路由中间件。 客户端路由中间件通常用于 Vue 路由的权限验证和重定向,而服务端路由中间件则通常用于来自客户端API请求认证和授权,以及数据和异常的预处理。
-
客户端路由中间件 (Nuxt4 目录结构: ~/app/middleware/xxx.ts)
// 例. Vue 路由拦截处理 => ~/app/middleware/auth.ts export default defineNuxtRouteMiddleware((to, from) => { if (to.params.id === '1') { return abortNavigation() // 阻止路由访问 } if (to.path == '/index') { return navigateTo('/') // 路由重定向 } })
<template> <div class="container"> Render Page Content </div> </template> <script setup lang="ts"> definePageMeta({ middleware: 'auth' // 使用中间件 }) </script>
官方文档 nuxt.com/docs/guide/…
推荐视频 www.youtube.com/watch?v=ua_… -
服务端路由中间件 (Nuxt4 目录结构: ~/server/middleware/xxx.ts)
// 例. Api Token 校验 export default defineEventHandler((event) => { const token = getRequestHeader(event, 'token') if (!token) { throw createError({ statusCode: 403, statusMessage: 'Token expired', }) } })
模块 Modules
Nuxt 模块是一个扩展和定制 Nuxt 应用的核心机制,它可以为你的项目导入组件库,集成第三方服务、自动化配置等,而无需你手动编写所有代码。
模块与插件区别
- 插件: 主要用于在应用启动时加载代码片段
- 模块: 主要用于更高层次的功能扩展和配置,通常在编译或构建阶段就已经工作
模块主要作用如下
- 增强功能: 扩展 Nuxt 功能,如 SEO 优化、分析工具、认证系统等。
- 集成服务: 集成第三方服务,如 Github 登录认证、数据库、API 服务等。
- 自动配置: 自动配置项目选项,如 导入 Ant Design Vue 模块, 则无需手动导入组件。
- 开发工具: 有些模块提供开发工具,如 代码生成、调试工具、热更新 等。
常用的官方和社区模块
- @nuxt/image:优化图像处理和加载的模块,支持懒加载、裁剪等功能。
- @nuxtjs/axios:集成 Axios HTTP 客户端,用于发出 API 请求和拦截处理。
- @nuxt/content:内容管理系统,支持基于文件系统的内容管理,如 Markdown。
- @nuxtjs/tailwindcss:无缝集成 Tailwind CSS,用于快速开发响应式设计。
如何使用模块?(以 Ant Design Vue 为例)
-
添加依赖项
@ant-design-vue/nuxt
npx nuxi@latest module add ant-design-vue
-
完善
nuxt.config.ts
配置选项export default defineNuxtConfig({ modules: [ '@ant-design-vue/nuxt' ], antd:{ // Options } })
-
项目中使用组件,无需手动导入
<template> <AButton @click="doClick"> 按钮 </AButton> </template> <script lang="ts" setup> const doClick = () => { message.info("按钮已触发"); } </script>
社区现有模块:nuxt.com/modules
开发模块文档:nuxt.com/docs/guide/…
服务端渲染 SSR
在 Nuxt SSR 模式下,客户端向服务器发出请求后,服务器会先执行相关的逻辑(如获取数据、渲染模板等),生成完整的 HTML 页面,并将其返回给客户端。客户端接收到页面后,立即展示给用户,同时在后台加载并激活 Vue 代码以进行后续的交互。
具体流程如下:
- 请求阶段:用户在浏览器中访问页面时,浏览器会向服务器发出请求。
- 服务器渲染:服务器接收到请求,执行数据获取、模板渲染,生成 HTML 页面。
- 返回 HTML:服务器将生成的 HTML 页面返回给浏览器。
- 浏览器展示:浏览器接收到 HTML 后,立即展示页面内容。
- 客户端激活:接下来 Vue 客户端脚本会加载激活,使页面具备交互能力。
这里服务端获取数据传输给客户端,Nuxt 称之为预渲染页面的有效负载,它一般是随着 html 页面一起返回。那么怎么样的数据获取才是真正的有效负载呢?
-
ref、reactive 等 Vue Api 不会生成预渲染页面有效负载
<template> <div class="container"> <div class="random"> random {{ random }} </div> <div class="data"> data {{ data }} </div> </div> </template> <script setup lang="ts"> let data = ref('') let random = ref(Math.random()) if (!data.value && import.meta.server) { data.value = 'server data' } if (!data.value && import.meta.client) { data.value = 'client data' } onMounted(() => { console.log('触发了生命周期 - 挂载钩子函数') }) </script>
上面 Vue 示例中
data
和random
不是预渲染有效负载。图示讲解说明: -
useState、useAsyncData 以及 useFetch 可以生成预渲染页面有效负载
<template> <div class="container"> <div class="random"> random {{ random }} </div> <div class="data"> data {{ data }} </div> </div> </template> <script setup lang="ts"> const random = useState(() => Math.random()) const { data } = await useAsyncData(() => new Promise(r => { if (import.meta.server) { return r('server data') } return r('client data') })) onMounted(() => { console.log('触发了生命周期 - 挂载钩子函数') }) </script>
图示讲解说明:
运行时配置 Runtime
在 Nuxt 中,运行时配置是指在应用运行时,动态设置或调整配置参数的功能。运行时配置通常用于设置环境相关的变量,例如 API 密钥、数据库连接字符串、或根据不同的部署环境(如开发、生产、测试等)切换配置。
推荐视频:www.youtube.com/watch?v=_FY…
运行时配置的用途
- 环境区分:根据不同的环境(开发、生产等)设置不同的选项,如 API 的基础 URL。
- 安全性:将敏感信息(密钥、数据库配置)存储在环境变量中,而不是代码硬编码。
- 灵活性:在不需要重新构建应用的情况下,可以动态调整某些配置参数。
运行时配置的示例
-
设置运行时配置
export default defineNuxtConfig({ runtimeConfig: { public: { apiBase: '/api' // 服务端和客户端都可用, 默认 '/api' }, apiSecret: 'key', // 仅服务端可用, 默认 'key' } })
-
项目中使用运行时配置
<template> <div class="container"> <div class="look-base-url"> {{ config.public.apiBase }} </div> <div class="look-user-data"> {{ data }} </div> </div> </template> <script setup lang="ts"> const config = useRuntimeConfig() const { data } = await useFetch('/api/user', { method: 'post', body: { apiSecret: import.meta.server ? config.apiSecret // 仅在服务端渲染时有值 : '' } }) </script>
-
如果构建了 node-server 模式下的前端项目,如何设定运行不同部署环境下的变量
# 测试环境 (apiBase: `/test/api`, apiSecret: `test-key`) NUXT_PUBLIC_API_BASE=/test/api NUXT_API_SECRET=test-key node .output/server/index.mjs # 正式环境 (apiBase: `/prod/api`, apiSecret: `prod-key`) NUXT_PUBLIC_API_BASE=/prod/api NUXT_API_SECRET=prod-key node .output/server/index.mjs
-
如果是构建了 node-server 模式下的前端项目,我们一般是通过 PM2 来设定变量和后台运行
// ecosystem.config.cjs module.exports = { apps: [ { name: "NuxtApp", // 表示 PM2 运行实例的唯一名称 autorestart: true, // 默认为 true, 发生异常的情况下自动重启 exec_mode: "cluster", // 多核 CPU 上运行多个实例 instances: "max", // max表示最大的 应用启动实例个数,仅在 cluster 模式有效 script: ".output/server/index.mjs", // 应用程序的启动脚本 // 生产环境运行时变量 env_production: { NUXT_PUBLIC_API_BASE: "/prod/api", NUXT_API_SECRET: "prod-key", }, // 测试环境运行时变量 env_test: { NUXT_PUBLIC_API_BASE: "/test/api", NUXT_API_SECRET: "test-key", }, }, ], };
# 运行 测试环境 pm2 start ecosystem.config.cjs --env test # 运行 正式环境 pm2 start ecosystem.config.cjs --env production
与 Vue 相比
搭建 Template 模版
使用 Nuxt 搭建模版相比于直接使用 Vue 搭建,具有以下几个优势:
-
Nuxt 提供了服务端渲染的能力,可以减少首屏加载时间,并能提供非常好的SEO优化。另外还可以借助于 <NuxtIsland> 来实现组件纯服务端渲染的能力,为一些涉及密钥等安全的页面提供保障。
-
Nuxt 提供了服务端引擎的能力,可以灵活地管理和扩展项目的服务端逻辑(API 路由的定义和代理等),同时允许为不同的部署环境构建输出 (传统服务器、无服务器环境、静态站点等)。
-
Nuxt 提供了强大的布局系统,可以轻松管理不同的页面布局,支持在页面中通过 definePageMeta 中的 layout 定义不同的布局适配,同时还支持 setPageLayout API 动态更改当前页面的布局。
-
Nuxt 提供文件系统路由可以自动生成页面路由,减少了手动配置的工作量。这在构建具有大量页面的后台管理系统时尤为便利。而在适配技术文档的模版上,Nuxt官方也提供了 @nuxt/content 功能上更胜于 vitepress 的模块,很轻松地实现由 Markdown 文件编写的技术文档网站。
-
Nuxt 内置了许多功能,如中间件、插件机制、模块系统等,这些功能可以极大地简化开发流程,使得开发各类模版更加高效。(如 开发后台管理系统模块,Nuxt有许多开箱即用的模块:Auth 模块、Axios 模块、PWA 模块、API 请求、缓存等)
-
Nuxt 提供了图层这一强大的共享和复用机制,允许你将应用的不同部分(如核心功能、主题等)拆分到独立的图层中。这种分离使得代码更加模块化和易于维护。同时也支持复用来自 npm 包的第三方图层而在使用中无需手动导入 ,这解决了我在搭建后台管理系统模版时碰到的困惑,即升级或修复后台管理系统时,如何同步已使用这个后台管理系统的更新。
渲染 Rendering 多样性
在之前的章节中,我们已经对单页应用(SPA)、服务端渲染(SSR)和 静态站点生成(SSG)的各个特点和应用场景都做了详细的说明。但 Nuxt 能为我们做的却远不止如此,它还提供了混合渲染,为复杂的业务场景做适配。
export default defineNuxtConfig({
routeRules: {
// 在构建时预渲染
'/': { prerender: true },
// 仅在客户端渲染呈现
'/spa/**': { ssr: false },
// 在 10 秒内重用这个缓存的响应
'/ten/**': { cache: { maxAge: 10 } },
// 在客户端不在发起远程 script 脚本的请求,仅 script 内联脚本可执行
'/no-js/**': { experimentalNoScripts: true },
// 页面按需生成,在后台重新验证,缓存直至 API 响应发生变化
'/products': { swr: true },
// 页面按需生成,在后台重新验证,缓存 1 小时(3600 秒)
'/products/**': { swr: 3600 },
// 页面按需生成,在后台重新验证,在 CDN 上缓存 1 小时(3600 秒),功能与 swr 类似
'/blog': { isr: 3600 },
// 页面在下次部署之前按需生成一次,缓存在 CDN 上
'/blog/**': { isr: true },
// 启用跨源资源共享(CORS)功能
'/api/**': { cors: true },
// 重定向处理
'/old-page': { redirect: '/new-page' },
// 返回响应时添加自定义 HTTP 头部 `x-magic-of`,其值为 `nuxt and vercel`
'/headers': { headers: { 'x-magic-of': 'nuxt and vercel' } },
}
})
SWR(Stale-While-Revalidate)
概念:是一种缓存策略,主要用于客户端数据获取和更新。它允许在数据过期(stale)后立即返回缓存的数据,同时在后台重新验证并获取新的数据。当新的数据被获取并更新缓存后,客户端会重新渲染组件。
- 缓存优先:
- SWR 首先返回缓存中的数据,这使得用户在请求数据时能立即看到旧的数据(即使数据过期)。
- 这意味着,即使数据被标记为过期,用户看到的仍然是缓存的旧数据。
- 后台重新验证:
- 在返回缓存数据后,SWR 会在后台发起一个新的请求以重新验证数据。
- 当新数据从服务器获取成功后,SWR 会更新缓存并触发组件的重新渲染,以展示最新的数据。
ISR(Incremental Static Regeneration)
概念:是一种用于静态网站生成的技术,可以在不重新构建整个网站的情况下,逐步更新静态页面。ISR 允许在构建后对特定页面进行增量更新,而不是重新生成整个站点。
- 服务器端缓存:ISR 主要用于服务器端缓存和更新。
- 定期更新:在一定时间间隔重新生成静态页面。生成后的内容会被缓存,直到下一个更新周期。
- 依赖平台:与 SWR 不同的是,它往往依赖平台(像 Vercel、Netlify),提供平台级性能。
- 性能优化:提高站点性能,减少重新生成整个站点的需要。
官方文档:nuxt.com/docs/guide/…
推荐视频:www.youtube.com/watch?v=Fp0…
Demo 演示:github.com/danielroe/n…
部署 Environment 灵活性
Nuxt 在部署环境和运行环境变量配置上非常灵活,在之前的章节中也有说明。
-
环境变量的配置
export default defineNuxtConfig({ runtimeConfig: { public: { apiBase: '/api' // 服务端和客户端都可用, 默认 '/api' }, apiSecret: 'key', // 仅服务端可用, 默认 'key' } })
-
可以创建 开发环境 .env.development、正式环境 .env.production 等环境变量文件,在构建时可以通过 --dotenv .env.development 或者 --dotenv .env.production 使用指定环境变量文件, 来覆盖默认的
apiBase
以及apiSecret
。 -
也可以设定运行时的环境配置,为现已构建的前端项目,动态适配不同的部署环境(正式环境、开发环境、测试环境)。关于这部分可以参考 运行时配置 Runtime
-
-
支持多种部署环境
-
静态站点托管:
Nuxt 静态站点生成功能可以将整个应用预渲染为静态 HTML 文件,部署在任何支持静态文件托管的服务上。例 GitHub Pages、Vercel、Netlify、或 Nginx 服务代理 -
Node 服务端托管:
Nuxt 可以通过服务器端渲染模式生成动态内容,这种方式需要一个支持 Node 环境的服务器,例如 通过 PM2 启动服务,或者第三方平台 AWS、Google Cloud Platform 等 -
边缘计算和无服务器架构:
通过无服务器架构或边缘计算,Nuxt 可以在全球范围内快速提供内容,减少延迟。例如 Vercel、Netlify Functions、Cloudflare Workers部署 Cloudflare,可以参考我这两个示例:
-
前端 Engineering 安全性
虽然前端应用的安全性在很大程度上依赖于良好的实践和策略 (如 内容安全策略CSP、Vue 模版转义、CSRF 防护),但 Nuxt 提供了一些强大的功能来确保前端应用的安全性。
-
运行时配置
从之前的章节中,我们了解到它是区别仅服务端可还是客户端可用。这就使得我们无需在客户端可见的代码中硬编码密钥等安全隐秘的信息。配合 useFetch 和 useAsyncData API 可以将数据传输给客户端,避免了由客户端发起请求而导致 url 及隐秘参数的暴露。 -
在 Vue 组件开发上
Nuxt 提供了更多的可能性(如 仅客户端渲染 <ClientOnly>, 仅开发期间使用 <DevOnly>),同时扩展 import.meta.server 和 import.meta.client 分别用来处理仅服务端执行和客户端执行的代码。此外,Nuxt 提供了 <NuxtIsland> 组件,它允许我们在一个 Vue 组件中引用纯服务端渲染组件,将涉及安全的交互交由服务端处理,客户端仅接收渲染后的 html 内容,进一步保障了前端的安全性。<NuxtIsland> 有关参考
推荐视频:www.youtube.com/watch?v=tYy…
推荐文章:www.vuemastery.com/blog/nuxts-… -
服务端引擎能力
使得我们可以编写服务端代码,连接数据库,实现更复杂的服务器端逻辑。比如,集成前端监控系统,方便客户/用户使用异常时,快速排查定位 bug 问题。