特点
- 基于文件的路由:根据
pages/目录的结构定义路由。 - 代码分割:Nuxt 会自动将您的代码分割成更小的块,这有助于减少应用程序的初始加载时间。
- 开箱即用的服务器端渲染:Nuxt 内置 SSR 功能,因此您不必自己设置单独的服务器。
- 自动导入:在各自的目录中编写 Vue 可组合和组件,并使用它们,而无需导入它们,并具有树抖动和优化的JS 包的好处。
- 数据获取实用程序:Nuxt 提供了可组合的工具来处理与 SSR 兼容的数据获取以及不同的策略。
- 零配置TypeScript支持:编写类型安全代码,而无需使用我们自动生成的类型和
tsconfig.json学习TypeScript - 已配置的构建工具:我们默认使用 Vite 来支持开发中的热模块替换(HMR),并将您的代码与最佳实践捆绑在一起用于生产。
在开发过程中,它使用 Rollup 和 Node.js worker 来进行服务器代码和上下文隔离。它还通过阅读 server/api/ 中的文件和 server/middleware/ 中的服务器中间件来生成您的服务器API。
Nuxt 由不同的核心包组成:
- 核心引擎:nuxt
- Bundlers: @nuxt/vite-builder 和 @nuxt/webpack-builder
- 命令行: nuxi
- 服务器引擎: nitro
- 开发工具包: @nuxt/kit
安装
Node.js - v18.0.0 或更新版本
npx nuxi@latest init <project-name>
配置
nuxt.config.ts 文件位于 Nuxt 项目的根目录,可以覆盖或扩展应用程序的行为。
环境变量
runtimeConfig 将环境变量等值暴露给应用程序的其他部分。默认情况下,这些密钥仅在服务器端可用。 runtimeConfig.public 中的键可以用于客户端。
// .env
# This will override the value of apiSecret
NUXT_API_SECRET=api_secret_token
<script setup lang="ts">
const runtimeConfig = useRuntimeConfig()
</script>
位于源目录 app.config.ts 文件用于公开可在构建时确定的公共变量。这些不能使用环境变量覆盖。
export default defineAppConfig({
title: 'Hello Nuxt',
theme: {
dark: true,
colors: {
primary: '#ff0000'
}
}
})
<script setup lang="ts">
const appConfig = useAppConfig()
</script>
runtimeConfig:需要在构建后使用环境变量或者私有或公共 token。app.config: 构建时使用公共 token ,网站配置,如主题变量,标题和任何不敏感的项目配置
| 特点 | runtimeConfig | app.config |
|---|---|---|
| 客户端 | Hydrated | Bundled |
| 环境变量 | ✅ Yes | ❌ No |
| Reactive | ✅ Yes | ✅ Yes |
| 类型支持 | ✅ Partial | ✅ Yes |
| 按请求配置 | ❌ No | ✅ Yes |
| 热模块替换 | ❌ No | ✅ Yes |
| 非原始 JS 类型 | ❌ No | ✅ Yes |
外部工具配置
| Name | Config File | How To Configure |
|---|---|---|
| Nitro | nitro.config.ts | Use nitro key in nuxt.config |
| PostCSS | postcss.config.js | Use postcss key in nuxt.config |
| Vite | vite.config.ts | Use vite key in nuxt.config |
| webpack | webpack.config.ts | Use webpack key in nuxt.config |
| Name | Config File | How To Configure |
|---|---|---|
| TypeScript | tsconfig.json | More Info |
| ESLint | eslint.config.js | More Info |
| Prettier | .prettierrc.json | More Info |
| Stylelint | .stylelintrc.json | More Info |
| TailwindCSS | tailwind.config.js | More Info |
| Vitest | vitest.config.ts | More Info |
vite 配置
vite.vue对应@vitejs/plugin-vuevite.vueJsx对应@vitejs/plugin-vue-jsx
// nuxt.config.ts
export default defineNuxtConfig({
vite: {
vue: {
customElement: true,
},
vueJsx: {
mergeProps: true,
},
},
});
视图
app.vue
入口文件,main.js nuxt 自动处理
components
大多数组件都是用户界面的可重用部分,如按钮和菜单
Pages
创建 pages/index.vue 文件并将 <NuxtPage /> 组件添加到 app.vue,pages/ 目录中添加新文件来创建更多页面及其相应的路由。
layouts
默认使用 layouts/default.vue 文件布局
<template>
<div>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</template>
扩展HTML模板
// server/plugins/extend-html.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
// This will be an object representation of the html template.
console.log(html)
html.head.push(`<meta name="description" content="My custom description" />`)
})
// You can also intercept the response here.
nitroApp.hooks.hook('render:response', (response, { event }) => { console.log(response) })
})
静态资源
public 目录用作静态资产的公共服务器,可以 / 获取 public/ 目录中的文件
<template>
<img src="/img/nuxt.png" alt="Discover Nuxt 3" />
</template>
Assets 经过构建,如样式表,字体 或 SVG,使用 ~/assets/ 路径引用位于 assets/ 目录中的文件。
<template>
<img src="~/assets/img/nuxt.png" alt="Discover Nuxt 3" />
</template>
全局样式导入
// assets/_colors.scss
$primary: #49240F;
$secondary: #E4A79D;
// nuxt.config
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "~/assets/_colors.scss" as *;',
},
},
},
},
});
样式
本地样式表可以放在 assets 目录,全局使用
<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>
export default defineNuxtConfig({
css: ['~/assets/css/main.css']
})
字体
字体文件放到 public 目录, assets 目录 css 文件引用
/* assets/css/main.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>
npm 样式
// app.vue
<script>
import 'animate.css'
</script>
<style>
@import url("animate.css");
</style>
// nuxt.config.ts
export default defineNuxtConfig({
css: ['animate.css']
})
CDN
// 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' }]
}
}
})
import { useHead } from 'unhead'
useHead({
link: [
{
rel: "stylesheet",
href: "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css",
},
],
});
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 单文件 JS 和 css 相互使用
<script setup lang="ts">
const color = ref("red")
</script>
<template>
<div class="text">hello</div>
</template>
<style>
.text {
color: v-bind(color);
}
</style>
<template>
<p :class="$style.red">This should be red</p>
</template>
<style module>
.red {
color: red;
}
</style>
使用 PostCSS
// nuxt.config.ts
export default defineNuxtConfig({
postcss: {
plugins: {
'postcss-nested': {}
"postcss-custom-media": {}
}
}
})
<style lang="postcss">
/* Write postcss here */
</style>
默认情况下,Nuxt 附带以下已预配置的插件:
- postcss-import:改进了
@import规则 - postcss-url:转换
url()语句 - autoprefixer:自动添加供应商前缀
- cssnano:压缩和清除
路由
pages 文件对应路由
导航
<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>
路由参数
<script setup lang="ts">
const route = useRoute()
// When accessing /posts/1, route.params.id will be 1
console.log(route.params.id)
</script>