从Nuxt 2升级到Nuxt 3:完整指南与实战经验
如果你正在考虑将项目从Nuxt 2升级到Nuxt 3,这篇文章会为你提供详细的指导。我们将讨论升级的好处、可能遇到的问题,以及具体的迁移步骤。
为什么要升级到Nuxt 3?
升级后的好处很明显。首先,打包后的文件体积更小。这意味着用户加载页面的速度更快。其次,本地开发服务器的启动速度明显提升,节省了开发时间。另外,你可以使用vue 3的语法,让代码更加清晰易读。
Nuxt 3还拆分了服务器层和客户端层,这让项目结构更加清晰。它不再集成Vuex,而是推荐使用Pinia。Pinia比Vuex更简单,使用起来也更方便。同时,Nuxt 3支持Vue 3和TypeScript,让你能跟上最新的技术趋势。
升级可能遇到的问题
Nuxt 3正式版发布的时间还不长,有些文档还不够完善。你在升级过程中可能会遇到一些问题,需要查阅相关包的文档来找到解决方案。但总的来说,升级的利大于弊。
如何升级?
升级并不是简单运行一条命令就能完成的。正确的方法是新建一个Nuxt 3项目,然后逐步迁移代码。这是因为Nuxt 3几乎完全重写了Nuxt 2,两者在结构和配置上有很大不同。
升级的主要工作包括以下几部分:
将Vue 2的代码改写成Vue 3的语法
修改项目配置
调整数据请求相关的代码
将Vuex迁移到Pinia
官方提供了迁移指南,你可以参考:https://nuxt.com/docs/migration/configuration
下面我们详细看看迁移的具体步骤。
项目配置的修改
配置方面的变化比较多。首先,建议在项目根目录下新建一个src文件夹,然后在nuxt.config.ts中设置srcDir: 'src/',将源码目录指向这个文件夹。
原来的module.exports写法要改成export default。同样,在配置中引入其他文件时,要使用import语句。
公共的head配置现在要放在app: {head: {}}里。publicRuntimeConfig和privateRuntimeConfig合并成了runtimeConfig。
代理配置也有变化。Nuxt 2中我们常用@nuxtjs/proxy来做代理,Nuxt 3中可以直接使用nitro配置:
nitro: {
devProxy: {
'/api/': {
target: 'http://your-api-url.com',
changeOrigin: true
}
}
}需要注意的是,devProxy只在开发模式下有效,构建后的版本不会有代理功能。
布局和页面
布局的使用方式有所变化。要指定页面使用的布局,可以在页面组件中这样写:
<script setup>
definePageMeta({
layout: "customLayout",
});
</script>页面和组件的命名规则基本没变,主要是将语法改为Vue 3的格式。
静态资源处理
assets目录用于存放样式、图片、字体等资源。public目录中的文件会直接放在服务器根目录下,不会经过构建处理,适合放置favicon.ico、robots.txt等文件。
迁移时直接把原来的目录结构搬过来就行。需要注意的是图片引用的方式:原来使用require('assets/img/x.png')的地方,要改成import x from 'assets/img/x.png'。
中间件
Nuxt 3区分了客户端和服务器端,这里的中间件指的是客户端中间件。它的主要作用是处理路由,比如参数过滤、重定向等。
例如,要实现根据设备类型重定向,可以先安装@nuxtjs/device包,然后在配置中启用:
modules: [
'@nuxtjs/device'
]在中间件中使用:
const { isMobile, isWindows, isMacOs } = useDevice();
export default defineNuxtRouteMiddleware((to, from) => {
if(isWindows){
return navigateTo('/win')
}
if(isMacOs){
return navigateTo('/mac')
}
})在页面中使用中间件:
<script setup>
definePageMeta({
middleware: ["device"]
})
</script>Composables目录
这是Nuxt 3新增的目录,里面的方法会自动导入到项目中,无需手动引入。你可以在页面、布局、插件和中间件中直接使用这些方法。
例如,在composables/timeTrans.ts中:
type TimeT = (time: number, format: string) => string;
export const timeTrans: TimeT = (time, format) => {
// 时间转换逻辑
return "xx:xx"
}在组件中直接使用:
<script setup>
const t = timeTrans(10202, "xx:xx")
</script>插件系统
Nuxt 2中需要在配置中指定插件是否在SSR中执行,Nuxt 3中可以通过文件命名来实现。例如,要让插件只在客户端执行,只需将文件命名为*.client.ts。
使用Element UI的例子:
import DragArc from 'drag-arc';
export default defineNuxtPlugin((NuxtApp) => {
return {
provide: {
DragArc: DragArc
}
}
})在组件中使用:
<script setup>
const { $DragArc } = useNuxtApp();
const dragArc = new $DragArc({
el: dom,
value: 10,
change: (v) => {
console.log(v)
}
})
</script>状态管理
Nuxt 3不再集成Vuex,推荐使用Pinia。首先安装:yarn add pinia @pinia/nuxt
创建store:
import { defineStore } from "pinia";
export const useMainStore = defineStore('main', {
state: () => ({
count: 1
}),
// 其他配置...
})Pinia比Vuex更简单直观,可以直接按文件拆分模块,actions支持同步和异步操作。
服务器端功能
这是Nuxt 3变化最大的部分,它将路由、插件、中间件等功能分离到了server目录。
创建API接口:
// server/api/hello.ts
export default defineEventHandler((event) => {
return {
api: 'world'
}
})访问/api/hello会返回{api: 'world'}。
路由处理:
// server/routes/[...].ts
import { sendProxy } from 'h3'
export default defineEventHandler(async (event) => {
const target = new URL(event.req.url, 'http://pyss.top');
return await sendProxy(event, target.toString());
});环境配置:
// env.js
const env = {
test: "https://test",
rc: "https://rc",
prod: "https://prod",
}在配置中使用:
import env from "./env"
export default defineNuxtConfig({
runtimeConfig: {
public: {
...env[process.env.MODE]
}
}
})中间件可以对所有请求进行处理:
// server/middleware/auth.ts
export default defineEventHandler((event) => {
event.node.req.headers['token'] = "12..."
})总结
从Nuxt 2升级到Nuxt 3确实需要一些工作量,但带来的好处是值得的。更好的性能、更清晰的代码结构、更现代化的开发体验,这些都让升级变得有意义。
升级过程需要耐心,建议先在一个小项目上尝试,熟悉了整个流程后再迁移重要项目。遇到问题时,可以查阅官方文档和相关包的文档。随着Nuxt 3生态的完善,升级过程会变得越来越简单。
希望这篇文章能帮助你顺利完成从Nuxt 2到Nuxt 3的升级。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!