一、项目搭建
1. 脚手架安装nuxt3
npx nuxi@latest init <project-name>
 
2. 安装ui框架
npm install -D @element-plus/nuxt
 
// nuxt.config.ts
export default defineNuxtConfig({modules: ['@element-plus/nuxt'],  //引入element-plus模块
})
 
3.安装pinia
npm install pinia @pinia/nuxt
 
如果安装失败,将以下内容添加到 package.json中
"overrides": {"vue": "latest"
}
 
// nuxt.config.ts
export default defineNuxtConfig({modules: ['@pinia/nuxt',],
})
 
二、nuxt.config.ts的一些配置
export default defineNuxtConfig({compatibilityDate: "2024-04-03",devtools: { enabled: true },modules: ["@element-plus/nuxt", "@pinia/nuxt"],  //导入模块css: ["element-plus/dist/index.css"],  //引入全局样式app: {head: {title: "nuxt3学习",  //全局设置网页标题,也可以在页面去设置局部标题meta: [{name: "description",content: "Nuxt 3",},],},},runtimeConfig:{  //运行时的配置,用于定义全局变量 用法下面的代码public:{  //public是服务端和客户端都能拿到值baseUrl:"localhost:3000"},abc:"123"  //只能服务端拿到值}
});
 
//获取runtimeConfig里面的值
const config = useRuntimeConfig();
console.log(config.abc,"config.abc");  //服务端打印123,客户端undefined
console.log(config.public.baseUrl,"config");  //服务端和客户端都一样
 
三 、路由
nuxt3使用的是约定式路由,只需要在根目录的pages页面中创建文件就行了,/路径对应的是index.vue文件,比如localhost:3000就会访问pages/index.vue文件,localhost:3000/login就会访问pages/login.vue,localhost:3000/users/test就会访问pages/users/test.vue这样就实现了嵌套路由.
-| pages/
---| index.vue   
---| login.vue
---| users/
-----| test.vue
-----| index.vue
 
命名路由
 使用方式和vue-router是一样的,通过localhost:3000/users/123访问
-| pages/
---| users/
-----| [abc].vue
 
const route = useRoute();
let abc= ref(route.params.abc); //获取命名路由传递的参数
 
可选路由
 localhost:3000/users/test和localhost:3000test访问的是同一个页面
-| pages/
---| [[user]]/
-----| test.vue
 
全局路由
 一般用于404页面,只要路由没有匹配上就来这个页面
-| pages/
---| [...abc].vue
 
vue-router里面的<router-view/>组件替换成了<NuxtPage />,当然也可以自定义路由,在页面中使用definePageMeta,路由跳转也变成了navigateTo,用法和router.push是一样的
definePageMeta({path:"/testLogin"
})
navigateTo("/testLogin"); 
 
局部路由守卫
 在根目录创建middleware文件夹,随便创建一个文件
//test.ts
export default defineNuxtRouteMiddleware((to, from) => {console.log(to,"to");
});
 
在需要的页面使用
definePageMeta({middleware:["test"]
});
 
全局路由守卫
 和局部路由守卫定义方式是一样的,只是命名方式不一样,abc.global.ts,需要在文件名中加入global,不需要在任何文件中使用就能全局路由拦截
四、composables文件夹
在这个文件夹里面的文件都会进行自动导出,但是只限于第一层,比如下面的test文件中的myTest.ts文件就不会自动导出,有两种导出方式,见下方代码
-| composables/
---| abc.ts
---test/
------myTest.ts
 
// abc.ts
export const add = (x, y) => {return x + y;
};
export default (x, y) => {return x + y;
};
 
console.log(add(1,2),"add");  //具名导出直接使用导出名
console.log(abc(1,2),"abc");  //默认导出使用文件名
 
五、useAsyncData
这个hook主要用于网络请求,如果直接使用$fetch('https://api.nuxtjs.dev/mountains'),那么服务端会执行一次,客户端也会执行一次,这样会增加服务器压力,所以使用useAsyncData会有一个缓存效果,当发现第一个参数也就是下面的mountains相同的时候,就直接使用缓存的数据,不会再执行里面的代码,类似于计算属性,useAsyncData必须返回一个promise
const { data, pending, error, refresh } = await useAsyncData('mountains',() => $fetch('https://api.nuxtjs.dev/mountains')
)
 
六、 网络请求封装
axios搭配useAsyncData来使用,在上面封装一层,也可以使用nuxt3提供的useFecth,也是封装一层,让所有的接口都走封装的方法,具体使用方法
const { data, pending, error, refresh } = await useFetch('/api/auth/login', {onRequest({ request, options }) {// 这里是请求拦截options.headers = options.headers || {}options.headers.authorization = '...'},onResponse({ request, response, options }) {//这里是响应拦截,不管成功还是失败都走这里// Process the response datareturn response._data},onResponseError({ request, response, options }) {//这里是失败的响应拦截}
})
 
7. state
const a = ref(0);
a.value++;
console.log(a.value,"a.value");  //1
 
上面这串代码会打印1,虽然服务端和客户端都执行了一次,但是每次a都重新赋值了,那么该如何让其打印2呢,第一种方法就是定义在runtimeConfig的public里面,第二种方式就是使用state
const test = useState("abc",() =>{return 0;
});
test.value++;
console.log(test.value,"test.value")   //2
 
这里的state是全局共享的,类似于pinia,可以在任何页面使用useState("test").value来获取值
8.打包发布
npm run build,执行文件在.output/server/index.mjs
