NuxtJS
Nuxt.js 是一个基于 Vue.js 的服务端渲染框架,它提供了许多优势和功能,因此使用 Nuxt.js 有以下几个主要理由:
服务端渲染
构建优化
开发体验
插件生态系统
静态站点生成
总的来说,使用 Nuxt.js 可以帮助你构建高性能、可伸缩和易于开发的 Vue.js 应用程序,尤其适用于需要服务端渲染和优化的项目。
快速入门
安装
npx nuxi@latest init 项目名
如果安装过程中出现了:
ERROR Error: Failed to download template from registry: fetch failed
可以这么做,打开电脑中这个文件 C:\Windows\System32\drivers\etc\hosts
编辑为以下内容:
199.232.69.194 github.global.ssl.fastly.net
185.199.108.153 assets-cdn.github.com
185.199.109.153 assets-cdn.github.com
185.199.110.153 assets-cdn.github.com
185.199.111.153 assets-cdn.github.com
配置 nuxt.config.ts
export default defineNuxtConfig({
// 是否开启调试
devtools: { enabled: true },
// 设置项目的源代码目录
srcDir: "src/",
// 是否开启自动配置路由
standalone: true,
// 开启更严格的TypeScript类型检查
typescript: {
strict: true
}
})
Public
在 public 目录中的文件在打包时不会参与编译,它会原封不动的复制到打包后的根目录中
这意味着 public 目录中的文件可以通过其相对路径直接在根网站进行访问,比如
项目中的目录: src/public/img
**可以通过: **http://xxx.xxx/img/xlb.jpg 直接访问
definePageMeta
在 definePageMeta 中定义的数据可以在布局页面接收并使用
<script setup lang="ts">
definePageMeta({
title: "首页",
// 这里的属性是自定义的
abc: 100
})
</script>
<template>
<div class="page">
<h1>首页</h1>
<NuxtLayout />
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route.meta); // {title: '首页', abc: 100}
</script>
Router
Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
在 Nuxt 中可以使用 NuxtLink、NuxtPage 替代 Vue 中的 RouterLink、RouterView
|访问路径| 组件位置&名称 |
|/|pages/index.vue|
| /user|pages/user.vue (优先) |
| /user|pages/user/index.vue |
| /user/one|pages/user/one.vue |
注意: 如果 pages 中有 pages/user.vue 和 pages/user/index.vue 同时存在,那么匹配的路由为前者 user.vue
路由跳转
虽然使用 Vue 中的 RouterLink 也可以实现跳转路由,但在 Nuxt 项目中建议使用 NuxtLink
<script setup lang="ts">
</script>
<template>
<h1>首页</h1>
<NuxtLink to="/login">跳转到登录页</NuxtLink>
</template>
<script setup lang="ts">
</script>
<template>
<h1>登录页</h1>
<NuxtLink to="/">跳转到首页</NuxtLink>
</template>
动态路由
目录结构: src/pages/user/[id].vue
访问: http://localhost:3000/user/10
<script setup lang="ts">
import { useRoute } from 'vue-router'
const id: string = useRoute().params.id as string
</script>
<template>
<h1>ID:{{ id }}</h1>
</template>
<style scoped lang="scss"></style>
目录结构: src/pages/user-[id].vue
访问: http://localhost:3000/user-10
<template>
<h1>用户ID:{{ $route.params.id }}</h1>
</template>
多级动态路由
目录结构: src/pages/user/[uid]/[aid].vue
访问: http://localhost:3000/user/1/3
<template>
<h1>用户ID:{{ $route.params.uid }}</h1>
<h1>文章ID:{{ $route.params.aid }}</h1>
</template>
使用 Vue 路由模式
如果觉得 Nuxt.js 自动配置路由不习惯,那么可以通过如下配置进行关闭,然后手动配置 router
export default defineNuxtConfig({
// 是否开启自动配置路由
standalone: true,
})
Components
自动引入
在 Nuxt3 中只要是在 components 目录下定义的组件,不需要手动引入,可以直接在页面中使用
<template>
<h1>A组件</h1>
</template>
<template>
<h1>B组件</h1>
</template>
```
嵌套组件
Components 目录下嵌套的组件以驼峰命名形式使用
Layouts
默认布局
如果没有指定布局,将使用 layouts/default.vue
接下来在 src/Layouts 目录中创建一个默认的布局:default.vue 文件
<script setup lang="ts">
</script>
<template>
<div>
<h1>这里埋葬着蟹老板的希望和梦想</h1>
<!-- 在布局文件中,页面的内容将显示在 <slot /> 组件中。 -->
<slot />
</div>
</template>
<style scoped lang="scss"></style>
在 app.vue 中将布局应用在所有页面,这样一来,所有页面都会被插槽到 default.vue 布局的指定位置
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
如果是多个插槽可以这么做
<template>
<div>
<h1>这里埋葬着蟹老板的希望和梦想</h1>
<slot name="header"/>
<slot name="body"/>
<slot name="footer"/>
</div>
</template>
<template>
<NuxtLayout>
<template #header>我是导航栏
<template #body>
<NuxtPage />
</template>
<template #footer>我是底部内容
</NuxtLayout>
</template>
如果应用程序中只有一个布局,建议使用 app.vue
自定义布局
当然,也可以指定一个布局:src/Layouts/page.vue
<template>
<h1>我是网页导航栏</h1>
<slot />
<h1>我是网页底部</h1>
</template>
在 src/pages/index.vue 文件中使用 page 布局
<template>
<NuxtLayout name="page">
<h1>我是网页核心内容</h1>
</NuxtLayout>
</template>
或
<script setup lang="ts">
definePageMeta({
layout: "page"
})
</script>
<template>
<NuxtLayout>
<h1>我是网页核心内容</h1>
</NuxtLayout>
</template>
关于 definePageMeta 的详细使用看这里:https://nuxt.com.cn/docs/api/utils/define-page-meta
独立页面
正常情况下,我们在 app.vue 中定义了所有页面的公共布局
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
这样一来不管是哪个路由访问,都会自带这个布局中的所有模块。虽然减少了大量重复的代码,但也带来了一个问题。
比如登录这样的页面是不需要用到公共布局的,它是一个独立页面。
所以可以这么做,给他定义一个 login.vue 页面与布局,然后把 definePageMeta 中的属性 layout 设置为 login,这样当页面访问 /login 时就会自动跳转到 login 布局
<script setup lang="ts">
definePageMeta({
layout: "login"
})
</script>
<template>
<h1>登录页</h1>
</template>
404页面
错误页面
动态更改布局
<script setup lang="ts">
const btn = () => {
// 动态更改布局
setPageLayout('login')
}
</script>
<template>
<button @click="btn">按钮</button>
</template>
注意点
其他组件不同,Layouts 布局和页面必须具有单个根元素,以允许 Nuxt 在布局更改时应用过渡效果-而且此根元素不能是
在模板中可以使用组件,但不能使用其他模板
Composables
在 composables 目录中所定义的业务逻辑代码会自动导入到你的应用程序中
目录结构: 在 src/composables/index.ts 中定义的数据导出后可以在所有页面使用,不需要手动导入
export const data = "Hello World!"
export const info = () => {
console.log("这里埋葬着蟹老板的希望和梦想");
return "这里埋葬着蟹老板的希望和梦想"
}
<script setup lang="ts">
</script>
<template>
<div>{{ data }}</div>
<div>{{ info() }}</div>
</template>
注意点
composables 目录中与 index.ts 同级或嵌套目录中的文件可以使用 index.ts 的数据,而 index.ts 无法使用其他文件的数据。可以通过 import 手动引入
默认情况下 Nuxt 只会扫描并导出 composables 目录中的顶级文件,像那些嵌套文件无法导出使用,我们可以进行如下配置让它扫描到嵌套模块并导出使用
export default defineNuxtConfig({
imports: {
dirs: [
// 扫描顶级模块
'composables',
// ... 或扫描带有特定名称和文件扩展名的一级嵌套模块
'composables/*/index.{ts,js,mjs,mts}',
// ... 或扫描给定目录中的所有模块
'composables/**'
]
}
})
扩展
process.client
通过该属性可以用于区分当前程序运行在服务端还是浏览器端,如果在浏览器端运行就返回 true 反之 false
if(process.client){
const token = localStorage.getItem("token")
console.log(token);
}
如果是运行环境是浏览器端的就允许使用浏览器的API,如果是服务端就不做处理
安装第三方包
在 Nuxt 项目中安装第三方包,就拿 Ant-design-vue 举例
在 plugins 目录中创建一个 antd.ts 文件,然后像往常一样导入相关文件,不同的是安装的语法与 Vue 略有差异
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css';
export default defineNuxtPlugin((nuxtApp) => {
// Vue 安装语法:createApp(App).use(Antd)
nuxtApp.vueApp.use(Antd);
})