资料网站
Nuxt: The Intuitive Vue Framework · Nuxt
Nuxt 中文站 - 直观的Web框架 Nuxt3文档 · Nuxt
追加补充
访问浏览器相关的对象
// 判断是否浏览器环境
if (process.browser) {
window.addEventListener("scroll", (e: Event) => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop >= 200) {
hideTopNav.value = true;
} else {
hideTopNav.value = false;
}
});
}
创建项目
优先按照官网文档的方式创建: Installation · Get Started with Nuxt
pnpm dlx nuxi@latest init <project-name>
如果创建报错,请参考这篇文章解决: 使用nuxi创建nuxt3项目报错 - 掘金 (juejin.cn)
默认的路径别名
~: 这个是nuxt3中默认的路径别名,表示项目根目录。
你要引入资源可以这样
import { fun } fomr '~/utils/test.ts'
配置文件
nuxt.config.ts
app.config.ts
Configuration · Get Started with Nuxt
页面与普通组件与布局组件
视图和组件都是自动引入的
app.vue
是界面的入口点
你不使用路由时
<template>
<div>
<h1>Welcome to the homepage</h1>
</div>
</template>
你使用路由,不使用布局组件时
<template>
<!-- 路由会渲染到这个地方 -->
<NuxtPage />
</template>
你既使用路由,又使用布局组件时
<template>
<!-- 这里会应用默认布局。即: 项目根目录/layouts/default.vue 这个文件 -->
<NuxtLayout>
<!-- 路由会渲染到这个地方 -->
<NuxtPage />
</NuxtLayout>
</template>
页面
- 页面必须放在
项目根目录/pages
普通组件
- 普通组件必须放在
项目根目录/components
布局组件
layouts/ · Nuxt Directory Structure
- 布局组件必须放在
项目根目录/layouts
使用默认布局组件
如果你仅有一个默认布局,那么直接将布局组件文件名,命名为:default.vue
项目根目录/layouts/default.vue
<template>
<div>
<AppHeader />
<!-- 这里的slot与vue中的默认slot用法一致 -->
<slot />
<AppFooter />
</div>
</template>
app.vue
<template>
<!-- 这里会应用默认布局。即: 项目根目录/layouts/default.vue 这个文件 -->
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
使用其他布局组件
项目根目录/layouts/other.vue 这是一个其他布局组件
在app.vue使用其他布局组件
app.vue
<script setup lang="ts">
// You might choose this based on an API call or logged-in status
const layout = "other";
</script>
<template>
<!-- 这里会应用默认布局。即: 项目根目录/layouts/other.vue 这个文件 -->
<NuxtLayout :name="layout">
<NuxtPage />
</NuxtLayout>
</template>
在其他页面使用其他布局组件
<script setup lang="ts">
definePageMeta({
// 这里layout默认为true,表示如果存在上级布局组件,当前页面是否需要包含在上级路由组件中。
layout: false,
})
</script>
<template>
<div>
<NuxtLayout name="custom">
<template #header> Some header template content. </template>
The rest of the page
</NuxtLayout>
</div>
</template>
使用静态资源
存放位置与访问方式
项目根目录/public
在vue文件中访问 public目录 资源
假设存在资源: 项目根目录/public/img/nuxt.png
<template>
<img src="/img/nuxt.png" alt="Discover Nuxt 3" />
</template>
项目根目录/assets
假设存在资源: 项目根目录/public/assets/nuxt.png
在vue文件中访问 assets目录 资源
<template>
<img src="~/assets/img/nuxt.png" alt="Discover Nuxt 3" />
</template>
样式, scss与字体文件
如需使用scss/sass 或 less 或 Stylus, 需要先安装对应插件
pnpm install sass
pnpm install less
pnpm install stylus
配置scss全局变量
nuxt.config.ts
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "~/assets/_colors.scss" as *;'
}
}
}
}
})
全局样式
nuxt.config.ts
export default defineNuxtConfig({
css: ['~/assets/css/main.css', '~/assets/scss/comm.scss']
})
nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
}
}})
任意vue组件
useHead({
link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
})
通过自定义Nitro插件引入
项目根目录/server/plugins/my-plugin.ts
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('render:html', (html) => {
html.head.push('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">')
})
})
某个vue组件单独引入样式(虽然是单独引入,但这些样式的效果对全局生效)
<script>
// Use a static import for server-side compatibility
import '~/assets/css/first.css'
// Caution: Dynamic imports are not server-side compatible
import('~/assets/css/first.css')
</script>
<style>
@import url("~/assets/css/second.css");
</style>
<style lang="scss">
@use "~/assets/scss/main.scss";
</style>
局部样式
<template>
<div class="example">hi</div>
</template>
<style scoped>
.example {
color: red;
}
</style>
css变量
<script setup lang="ts">
const color = ref("red")
</script>
<template>
<div class="text">hello</div>
</template>
<style scoped>
.text {
color: v-bind(color);
}
</style>
字体文件
字体文件也应该放在项目根目录/public
假设有字体文件项目根目录/public/font/FarAwayGalaxy.woff
在css文件中引入字体文件
@font-face {
font-family: 'FarAwayGalaxy';
src: url('/fonts/FarAwayGalaxy.woff') format('woff');
font-weight: normal;
font-style: normal;
font-display: swap;
}
使用指定字体
<style>
h1 {
font-family: 'FarAwayGalaxy', sans-serif;
}
</style>
路由管理
Routing · Get Started with Nuxt
- 路由中间件必须全部放在
项目根目录/routes目录 - 路由组件必须全放在
项目根目录/pages目录 - 与
nuxt2不同的是,nuxt3不会在.nuxt目录生成静态路由配置文件 - 默认的路由名是文件名
test.vue的路由名是test,hello/index.vue的路由名是hello,hello/demo.vue的路由名是hello-demo
开发环境,可以通过nuxt devtool查看所有路由path,以及对应路由名, 和对应路由使用的中间件,以及该路由使用的布局组件
| pages/
---| about.vue
---| index.vue
---| posts/
-----| [id].vue
路由导航
<template>
<header>
<nav>
<ul>
<li><NuxtLink to="/about">About</NuxtLink></li>
<li><NuxtLink to="/posts/1">Post 1</NuxtLink></li>
<li><NuxtLink to="/posts/2">Post 2</NuxtLink></li>
</ul>
</nav>
</header>
</template>
const $router = useRouter();
function onClick() {
$router.push({ path: "/" });
}
获取路由参数
<script setup lang="ts">
const route = useRoute()
// When accessing /posts/1, route.params.id will be 1
console.log(route.params.id)
// 获取所有查询参数对象
const query = route.query;
// 或者直接获取某个特定查询参数
const exampleParam = route.query.example;
</script>
多级路由参数
多级路由参数可以通过创建嵌套的文件夹结构来实现。例如,假设你有一个产品目录系统,需要根据类别、品牌和产品ID访问不同产品详情页面,你可以按照以下方式设置多级动态路由:
- pages/
|-- product/
|-----| _category/ # 动态一级参数:类别 -
|-----|-----| _brand/ # 动态二级参数:品牌 -
|-----|-----|----| _id.vue # 动态三级参数:产品ID
export default {
setup() {
const route = useRoute();
// 获取路由参数
const category = route.params.category; // "categoryA"
const brand = route.params.brand; // "brandB"
const id = route.params.id; // "product123"
// ...
}
};
路由中间件
定义路由中间件
function isAuthenticated(): boolean { return false }
// ---cut---
export default defineNuxtRouteMiddleware((to, from) => {
// isAuthenticated() is an example method verifying if a user is authenticated
if (isAuthenticated() === false) {
return navigateTo('/login')
}
})
在页面中使用路由中间件
<script setup lang="ts">
definePageMeta({
middleware: 'auth'
})
</script>
<template>
<h1>Welcome to your dashboard</h1>
</template>
嵌套路由
使用<NuxtChild> 组件用于在父级路由组件中渲染嵌套路由对应的子组件
嵌套路由结构
嵌套路由结构说明
父路由组件可以叫任意名称,子路由组件,必须放在和父路由组件同层级的同名文件夹下,这时nuxt3就会给你生成嵌套路由。
上面例子parent.vue是父路由组件,parent文件夹用于存放子路由。
parent.vue要能渲染子路由需要这么做:
<template>
<!-- 子页面的出口 -->
<NuxtChild />
</template>
状态管理
State Management · Get Started with Nuxt
注意: ts的定义是自动默认引入的无需手动引入,如果出现找不到名称“defineStore”这种ts类型错误,那重新启动一次本地nuxt服务,等待imports.d.ts生成相关的全局类型定义
那么你的store定义大概是这样的
使用定义的store大概是这样的
使用pina进行状态管理
pnpm add @pinia/nuxt
nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
// 引入`@pinia/nuxt`
modules: ["@pinia/nuxt"],
// 指定pinia的store存放目录
pinia: {
storesDirs: ["./stores/**"],
},
$production: {
routeRules: {
"/**": { isr: true },
},
},
});
nuxt3中使用pinia无需像vite + vue3项目中在某个地方进行初始化,直接在vue组件中使用即可
nuxt3中使用pinia无需像vite + vue3项目中在某个地方进行初始化,直接在vue组件中使用即可
数据获取
Data fetching · Get Started with Nuxt
错误处理
Error Handling · Get Started with Nuxt
浏览器兼容性
关于Nuxt3.6兼容低版本游览器的实战以及可能存在的问题_nuxt-vite-legacy-CSDN博客
部署发布
Deployment · Get Started with Nuxt
使用第三方模块
nuxt3官方收录模块
animate.css
pnpm add animate.css
可以直接在app.vue中引入,或某个具体页面中引入
<script>
import 'animate.css'
</script>
<style>
@import url("animate.css");
</style>
也可以在nuxt.config.ts中作为全局资源引入
export default defineNuxtConfig({
css: ['animate.css']
})
tailwind css
Config - Nuxt Tailwind (nuxtjs.org)
pnpm install -D @nuxtjs/tailwindcss
nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/tailwindcss']
})
创建tailwind css配置文件
npx tailwindcss init
import type { Config } from 'tailwindcss'
import colors from 'tailwindcss/colors'
export default <Partial<Config>>{
theme: {},
plugins: [],
content: [
`${srcDir}/components/**/*.{vue,js,ts}`,
`${srcDir}/layouts/**/*.vue`,
`${srcDir}/pages/**/*.vue`,
`${srcDir}/composables/**/*.{js,ts}`,
`${srcDir}/plugins/**/*.{js,ts}`,
`${srcDir}/utils/**/*.{js,ts}`,
`${srcDir}/App.{js,ts,vue}`,
`${srcDir}/app.{js,ts,vue}`,
`${srcDir}/Error.{js,ts,vue}`,
`${srcDir}/error.{js,ts,vue}`,
`${srcDir}/app.config.{js,ts}`
]
}
tailwind其他配置详见:Configuration - Tailwind CSS
~/assets/css/tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;