什么是Nuxt
在了解 Nuxt 之前,我们先来了解一下创建一个现代应用程序,所需的技术:
- 支持数据双向绑定 和 组件化( Nuxt 选择了Vue.js )。
- 处理客户端的导航( Nuxt 选择了vue-router )。
- 支持开发中热模块替换和生产环境代码打包( Nuxt支持webpack 5和Vite )。
- 兼容旧版浏览器,支持最新的 JavaScript 语法转译( Nuxt使用esbuild )。
- 应用程序支持开发环境服务器,也支持服务器端渲染 或 API接口开发。
- Nuxt 使用 h3来实现部署可移植性(h3是一个极小的高性能的http框架)
- 如:支持在 Serverless、Workers 和 Node.js 环境中运行。
Nuxt 是一个 直观的 Web 框架
- 自 2016 年 10 月以来,Nuxt专门负责集成上述所描述的事情 ,并提供前端和后端的功能。
- Nuxt 框架可以用来快速构建下一个 Vue.js 应用程序,如支持 CSR 、SSR、SSG 渲染模式的应用等。
- 官网地址: nuxt.com/
Nux3的特点
- Vue技术栈:Nuxt3 是基于 Vue3 + Vue Router + Vite 等技术栈,全程 Vue3+Vite 开发体验(Fast)。
- 自动导包,Nuxt 会自动导入辅助函数、组合 API和 Vue API ,无需手动导入。
- 基于规范的目录结构,Nuxt 还可以对自己的组件、 插件使用自动导入。
- 约定式路由(目录结构即路由)Nuxt 路由基于vue-router,在 pages/ 目录中创建的每个页面,都会根据目录结构和文件名来自动生成路由
- 渲染模式:Nuxt 支持多种渲染模式(SSR、CSR、SSG等)
- 利于搜索引擎优化:服务器端渲染模式,不但可以提高首屏渲染速度,还利于SEO
- 服务器引擎 : 在开发环境中,它使用 Rollup 和 Node.js 。
- 在生产环境中,使用 Nitro 将您的应用程序和服务器构建到一个通用.output目录中。Nitro服务引擎提供了跨平台部署的支持,包括 Node、Deno、Serverless、Workers等平台上部署。
Nuxt3 环境搭建
◼ 在开始之前,请确保您已安装推荐的设置:
- Node.js (最新 LTS 版本,或 16.11以上)
- VS Code ✓ Volar、ESLint、Prettier
◼ 命令行工具,新建项目(hello-nuxt )
- 方式一:npx nuxi init hello-nuxt
- 方式二:pnpm dlx nuxi init hello-nuxt
- 方式三:npm install –g nuxi && nuxi init hello-nuxt
◼ 运行项目: cd hello-nuxt yarn install
- pnpm install --shamefully-hoist(创建一个扁平的 node_modules 目录结构,类似npm 和 yarn)
- yarn dev
Nuxt3 目录结构
文件详情
package.json Nuxt脚本介绍
应用入口(App.vue)
默认情况下,Nuxt 会将此文件视为入口点,并为应用程序的每个路由呈现其内容,常用于:
- 定义页面布局Layout 或 自定义布局,如:NuxtLayout
- 定义路由的占位,如:NuxtPage,编写全局样式,全局监听路由(因为之前介绍到Nuxt是约定式路由,所以并没有路由配置文件) 等等
<template>
<div>
<NuxtWelcome />
</div>
</template>
<script setup>
//监听全局路由
let router = useRouter()
router.beforeEach((to, from, next) => {
// 路由跳转前的钩子
console.log('路由跳转前的钩子')
next()
})
</script>
配置文件(nuxt.config.ts)
nuxt.config.ts 配置文件位于项目的根目录,可对Nuxt进行自定义配置。
比如,可以进行如下配置: runtimeConfig:运行时配置,即定义环境变量
- 可通过.env文件中的环境变量来覆盖,优先级(.env > runtimeConfig)
- .env的变量会打入到process.env中,符合规则的会覆盖runtimeConfig的变量
- .env一般用于某些终端启动应用时动态指定配置,同时支持dev和pro
如:在runtimeConfig中配置变量
export default defineNuxtConfig({
devtools: { enabled: true }, //启动开发者工具
runtimeConfig: {
// 运行时配置
appKey: "Jack", //server
public: {
baseURL: "http://codercba.com", // server and client
},
},
});
在app.vue中使用
//1.判断代码执行环境
if (process.server) {
console.log('运行在 server');
}
if (process.client) {
console.log('运行在 client');
}
//1.读取运行时的配置
const runtimeConfig = useRuntimeConfig()
if (process.server) {
console.log(runtimeConfig.appKey); //jack
console.log(runtimeConfig.public.baseURL); //'http://codercba.com'
}
if (process.client) {
console.log(runtimeConfig.appKey); //undefined
console.log(runtimeConfig.public.baseURL);//'http://codercba.com'
}
如果我 此时新建一个.env文件
# 环境变量 .env
NUXT_APP_KEY = 'DDDDDDD'
那么这个时候就会覆盖之前的配置文件中的appKey
appConfig: 应用配置,定义在构建时确定的公共变量,如:theme
- 配置会和 app.config.ts 的配置合并(优先级 app.config.ts > appConfig)
可以在nuxt.config.ts 中配置应用配置
//定义应用的配置
appConfig: {
title: "Hello Nuxt LUABU",
theme: {
primary: "blue",
},
},
在app.vue中获取使用
let appConfig = useAppConfig()
//server client
console.log(appConfig.title);
console.log(appConfig.theme.primary);
onMounted(() => {
document.title = appConfig.title
})
当数据过多,也可以在文件目录里面新建一个app.config.ts的文件去储存。
app:app配置
- head:给每个页面上设置head信息,也支持 useHead 配置和内置组件。
app所有的head添加的配置(SEO优化,加载外部资源)
app: {
//app所有的head添加的配置(SEO优化,加载外部资源)
head: {
title: "luabu",
charset: "UTF-8",
viewport: "width=device-width, initial-scale=1",
meta: [
{
name: "keywords",
content: "Luabu Nuxt3",
},
{
name: "description",
content: "学习网站",
},
],
link: [
{
rel: "shortcut icon",
href: "favicon.ico",
type: "image/x-icon",
},
],
style: [
{
children: `body{ color: red}`,
},
],
script: [
{
src: "http://baidu.com",
},
],
},
也可以动态添加
组件
<Head>
<Meta name="Key" content="key key"></Meta>
</Head>
动态添加app所有的页面添加head的内容
useHead({
title: 'app useHead'
})
ssr:指定应用渲染模式
router:配置路由相关的信息,比如在客户端渲染可以配置hash路由
alias:路径的别名,默认已配好
modules:配置Nuxt扩展的模块,比如:@pinia/nuxt @nuxt/image
routeRules:定义路由规则,可更改路由的渲染模式或分配基于路由缓存策略(公测阶段)
builder:可指定用 vite 还是 webpack来构建应用,默认是vite。如切换为 webpack 还需要安装额外的依赖。
runtimeConifg vs app.config
runtimeConfig 和 app.config都用于向应用程序公开变量。要确定是否应该使用其中一种,以下是一些指导原则:
- runtimeConfig:定义环境变量,比如:运行时需要指定的私有或公共token。
- app.config:定义公共变量,比如:在构建时确定的公共token、网站配置。
Nuxt3 内置组件
◼ Nuxt3 框架也提供一些内置的组件,常用的如下:
- SEO组件: Html、Body、Head、Title、Meta、Style、Link、NoScript、Base
- NuxtWelcome:欢迎页面组件,该组件是 @nuxt/ui的一部分 NuxtLayout:是 Nuxt 自带的页面布局组件 NuxtPage:是 Nuxt 自带的页面占位组件
- ✓ 需要显示位于目录中的顶级或嵌套页面 pages/
- ✓ 是对 router-view 的封装
- ClientOnly:该组件中的默认插槽的内容只在客户端渲染
- ✓ 而fallback插槽的内容只在服务器端渲染
- NuxtLink:是 Nuxt 自带的页面导航组件
- ✓ 是 Vue Router组件 和 HTML < a > 标签的封装
全局样式
编写全局样式步骤
1.在assets中编写全局样式,比如:globel.scss
2.接着在nuxt.config中的css选项中配置
3.接着执行npm i –D sass 即可
css: ["@/assets/styles/main.css", "@/assets/styles/global.scss"],
定义全局变量步骤
1.在assets中编写全局样式变量,比如:_colors.scss
2.接着在nuxt.config中的vite选项中配置
3.然后就可以在任意组件中或scss文件中直接使用全局变量
$fsColor: purple;
$fs20: 20px;
@mixin border(){
border: 1px solid red
}
<style scoped lang="scss">
@import './assets/styles/variables.scss';
.global-style4 {
color: $fsColor;
font-size: $fs20;
@include border();
}
</style>
资源的导出
◼ public目录
用作静态资产的公共服务器,可在应用程序上直接通过 URL 直接访问
比如:引用public/img/ 目录中的图像文件
✓ 在静态 URL 中可用 /img/nuxt.png,
✓ 静态的URL也支持在背景中使用
◼ assets目录
assets经常用于存放如样式表、字体或 SVG的资产
可以使用 ~/assets/ 路径引用位于assets目录中的资产文件
~/assets/ 路径也支持在背景中使用
◼ 字体图标,字体图标使用步骤
1.将字体图标存放在assets目录下
2.字体文件可以使用 ~/assets/ 路径引用。
3.在nuxt.config配置文件中导入全局样式
4.在页面中就可以使用字体图标了
创建页面
◼ Nuxt项目中的页面是在 pages目录 下创建的
◼ 在pages目录创建的页面,Nuxt会根据该页面的目录结构和其文件名来自动生成对应的路由。
◼ 页面路由也称为文件系统路由器(file system router),路由是Nuxt的核心功能之一
◼ 新建页面步骤
1.创建页面文件,比如: pages/index.vue
2.将 内置组件添加到 app.vue
3.页面如果使用scss那么需要安装:npm i sass -D
◼ 命令快速创建页面
npx nuxi add page home # 创建home页面
npx nuxi add page detail/[id] # 创建detail页面
npx nuxi add page user-[role]/[id] # 创建user页面
组件导航(NuxtLink)
◼ 是Nuxt内置组件,是对 RouterLink 的封装,用来实现页面的导航。
- 该组件底层是一个
<a>标签,因此使用 a + href 属性也支持路由导航 - 但是用a标签导航会有触发浏览器默认刷新事件,而 NuxtLink 不会,NuxtLink还扩展了其它的属性和功能
◼ 应用Hydration后(已激活,可交互),页面导航会通过前端路由来实现。这可以防止整页刷新
◼ 当然,手动输入URL后,点击刷新浏览器也可导航,这会导致整个页面刷新
◼ NuxtLink 组件属性:
- to:支持路由路径、路由对象、URL
- href:to的别名
- activeClass:激活链接的类名
- target:和a标签的target一样,指定何种方式显示新页面
- 等等
<NuxtLink to="/home">
<button>home</button>
</NuxtLink>
<NuxtLink :to="{
path: 'category',
query: {
id: 1
}
}">
<button>category</button>
</NuxtLink>
<NuxtLink to="/cart/1">
<button>cart</button>
</NuxtLink>
编程导航
Nuxt3除了可以通过<NuxtLink>内置组件来实现导航,同时也支持编程导航:navigateTo 。
通过编程导航,在应用程序中就可以轻松实现动态导航了,但是编程导航不利于SEO。
navigateTo 函数在服务器端和客户端都可用,也可以在插件、中间件中使用,也可以直接调用以执行页面导航,例如:
- 当用户触发该goToProfile()方法时,我们通过navigateTo函数来实现动态导航。
- 建议: goToProfile方法总是返回 navigateTo 函数(该函数不需要导入)或 返回异步函数
◼ navigateTo( to , options) 函数:
to: 可以是纯字符串 或 外部URL 或 路由对象
options: 导航配置,可选
-
✓ replace:默认为false,为true时会替换当前路由页面
-
✓ external:默认为false,不允许导航到外部连接,true则允许
const goToCard = () => {
// return navigateTo('/cart')
return navigateTo({
path: '/cart',
query: {
id: 200
}
}, {
replace: true, //是否替换当前的页面
})
}
◼ Nuxt3中的编程导航除了可以通过 navigateTo 来实现导航,同时也支持 useRouter ( 或 Options API 的 this.$router )
◼ useRouter常用的API
- back:页面返回,和 一样 router.go(-1)
- forward:页面前进,同 router.go(1)
- go:页面返回或前进,如 router.go(-1) or router.go(1)
- push:以编程方式导航到新页面。建议改用 navigateTo 。支持性更好
- replace:以编程方式导航到新页面,但会替换当前路由。建议改用 navigateTo 。支持性更好
- beforeEach:路由守卫钩子,每次导航前执行(用于全局监听)
- afterEach:路由守卫钩子,每次导航后执行(用于全局监听)
动态路由
Nuxt3 和 Vue一样,也是支持动态路由的,只不过在Nuxt3中,动态路由也是根据目录结构和文件的名称自动生成。
◼ 动态路由语法:
-
页面组件目录 或 页面组件文件都 支持 [ ] 方括号语法
-
方括号里编写动态路由的参数
◼ 例如,动态路由 支持如下写法:
- pages/detail/[id].vue-> /detail/:id
- pages/detail/user-[id].vue-> /detail/user-:id
- pages/detail/[role]/[id].vue -> /detail/:role/:id
- pages/detail-[role]/[id].vue -> /detail-:role/:id
◼ 注意事项:
**动态路由 和 index.vue **不能同时存在, Next.js则可以
路由参数
◼ 动态路由参数
- 1.通过 [] 方括号语法定义动态路由,比如:/detail/[id].vue
- 2.页面跳转时,在URL路径中传递动态路由参数,比如:/detail/10010
- 3.目标页面通过 route.params 获取动态路由参数
◼ 查询字符串参数
- 1.页面跳转时,通过查询字符串方式传递参数,比如:/detail/10010?name=liujun
- 2.目标页面通过 route.query 获取查询字符串参数
404 Page
捕获所有不配路由(即 404 not found 页面)
- 通过在方括号内添加三个点 ,如:[...slug].vue 语法,其中slug可以是其它字符串。
- 除了支持在 pages根目录下创建,也支持在其子目录中创建。
- Nuxt3正式版不支持404.vue页面了,以前的候选版是支持的404.vue,但是Next.js是支持。
路由匹配规则
◼ 路由匹配需注意的事项
预定义路由优先于动态路由,动态路由优先于捕获所有路由。请看以下示例:
✓ 1.预定义路由:pages/detail/create.vue
➢ 将匹配 /detail/create
✓ 2.动态路由:pages/detail/[id].vue
➢ 将匹配/detail/1, /detail/abc 等。
➢ 但不匹配 /detail/create 、/detail/1/1、/detail/ 等
✓ 3.捕获所有路由:pages/detail/[...slug].vue
➢ 将匹配 /detail/1/2, /detail/a/b/c 等。
➢ 但不匹配 /detail 等
嵌套路由
Nuxt 和 Vue一样,也是支持嵌套路由的,只不过在Nuxt中,嵌套路由也是根据目录结构和文件的名称自动生成。
◼ 编写嵌套路由步骤:
- 1.创建一个一级路由,如:parent.vue
- 2.创建一个与一级路由同名同级的文件夹,如: parent
- 3.在parent文件夹下,创建一个嵌套的二级路由
✓ 如:parent/child.vue, 则为一个二级路由页面
✓ 如: parent/index.vue 则为二级路由默认的页面
4.需要在parent.vue中添加 NuxtPage 路由占位