样式方案
本教程共 50 篇 · 第 29 篇 · 更新于 2026-08-08 · 约 8 分钟阅读
本节目标:掌握在 Nuxt 项目里写样式的几种方式,能根据场景选择全局样式、组件局部样式或 Tailwind,并知道怎么用 SCSS 这类预处理器。
Nuxt 在样式这件事上非常「佛系」——它不强迫你用某一种写法。你可以写原生 CSS,可以用 SCSS 这种预处理器,也能直接上 Tailwind、UnoCSS 这类原子化框架,甚至能用 UI 库。对刚上手的朋友来说,先搞清楚「样式写在哪、作用范围多大」比纠结用哪个工具更重要。
29-1
在 Nuxt 里给页面加样式,本质上分两条路:全局样式和局部样式。
全局样式会被注入到所有页面,比如你写了一个统一的字体、背景色或重置样式(reset),希望整站都生效,就适合放在全局。局部样式则只服务于某一个组件,组件卸载了样式也就不产生影响,不会「串味」到别处。
Tip一个简单判断标准:如果这个样式只属于某个按钮、某张卡片,就写在组件自己的
<style>块里;如果全站都要用,就放进app/assets/下的样式文件,再用下面说的方式引入。
Nuxt 4 约定把样式、图片、字体这类「需要构建工具处理」的资源放在 app/assets/ 目录。路径前缀用 ~/assets/,例如 ~/assets/css/main.css。注意 assets 不是自动扫描目录,你写了文件不会自动生效,必须显式引入。
29-2
最省事的全局样式写法,是在 nuxt.config.ts 里用 css 字段声明。Nuxt 会把这些样式表内联进每一页的 HTML,全站都能用。
export default defineNuxtConfig({
css: ['~/assets/css/main.css'],
})
body {
margin: 0;
font-family: system-ui, sans-serif;
background: #f7f7f8;
color: #1f2328;
}
Note用
css配置项引入的样式,会被打包进每一个页面的渲染结果里。如果样式很多又只在某些页面用,更推荐在对应组件里按需引入,避免无谓的体积膨胀。
除了在配置里写,你也能在组件里用 import 直接引入本地样式文件:
<script setup lang="ts">
// 静态导入,服务端也能正常工作
import '~/assets/css/main.css'
</script>
<template>
<NuxtPage />
</template>
Warning尽量用静态
import '~/assets/css/main.css'。动态import('~/assets/css/main.css')在服务端渲染(SSR)下不兼容,容易在生产环境踩坑。
29-3
Vue 单文件组件(SFC)最舒服的一点,就是能在 .vue 文件里直接写 <style>。加上 scoped 属性后,这些样式只作用于当前组件,Nuxt 会自动给元素加一个特殊属性做隔离。
<template>
<div class="card">
<p class="title">你好,Nuxt</p>
</div>
</template>
<style scoped>
.card {
padding: 16px;
border-radius: 12px;
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.title {
font-weight: 600;
color: #2563eb;
}
</style>
这样哪怕别的组件也有 .title,也不会被这里的蓝色影响。对初学者来说,scoped 基本是默认选项,能帮你少掉很多「样式互相打架」的烦恼。
除了 scoped,Vue 还支持 <style module>,它会把类名编译成带哈希的局部名称,通过 $style 变量引用。日常开发里 scoped 用得更多,知道有这个选项即可。
29-4
样式常常要跟着状态变。Vue 提供了 :class 和 :style 两种绑定,特别适合「选中态」「报错态」这类场景。
<script setup lang="ts">
const isActive = ref(true)
const hasError = ref(false)
</script>
<template>
<div class="static" :class="{ active: isActive, 'text-danger': hasError }">
状态文字
</div>
</template>
<style scoped>
.active {
color: #16a34a;
}
.text-danger {
color: #dc2626;
}
</style>
还有一个很妙的能力:在 <style> 里用 v-bind 直接引用脚本里的变量,变量一变样式就跟着变。
<script setup lang="ts">
const color = ref('red')
</script>
<template>
<p class="text">颜色会跟着变量变</p>
</template>
<style scoped>
.text {
color: v-bind(color);
}
</style>
29-5
原生 CSS 写多了会觉得重复、不好维护。预处理器能让你用变量、嵌套、混合(mixin)等语法,写起来更顺。Nuxt 默认用 Vite 构建,对 .scss、.sass、.less、.styl、.stylus 都有内置支持,只要先装好对应的包。
# 以 SCSS 为例
npm install -D sass
装好后,在组件里直接写 lang="scss" 就能用:
<style lang="scss" scoped>
$primary: #2563eb;
.card {
padding: 16px;
border: 1px solid $primary;
.title {
color: $primary;
font-weight: 600;
}
}
</style>
如果有一组全局变量(比如品牌色),可以在 nuxt.config.ts 里通过 Vite 的预处理器选项自动注入,省得每个文件都手动 @use:
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "~/assets/_colors.scss" as *;',
},
},
},
},
})
Tip把颜色、间距这类设计变量集中在一个
_colors.scss里,全站统一引用,以后换主题只改一个文件。这是预处理器最实用的玩法之一。
29-6
Tailwind 是当下很火的「原子化 CSS」框架:你不在 .css 里写规则,而是直接在 HTML 元素上拼类名,比如 <div class="p-4 rounded bg-white shadow">。Nuxt 团队和社区都提供了现成模块,集成很轻松。
最省事的方式是用 Nuxt CLI 一键添加官方社区模块 @nuxtjs/tailwindcss:
npx nuxi@latest module add tailwindcss
这条命令会把模块加进 nuxt.config.ts 的 modules,并自动创建 app/assets/css/tailwind.css。你只要在这个文件里放好指令,再在 app.vue 引入即可:
@tailwind base;
@tailwind components;
@tailwind utilities;
<script setup lang="ts">
import '~/assets/css/tailwind.css'
</script>
<template>
<div class="p-8 text-center">
<h1 class="text-2xl font-bold text-blue-600">Hello Nuxt + Tailwind</h1>
</div>
</template>
NoteTailwind v4 换了新的引擎,官方也提供了
@tailwindcss/vite插件,可以直接在 Vite 配置里启用,不走@nuxtjs/tailwindcss模块。新手先用上面的模块方式最稳,想追新再研究 v4 原生集成。
用 Tailwind 时有个常见误区:别为了「少写重复类名」而滥用 @apply 去全局改元素选择器(比如 div { @apply ... })。这会把样式悄悄绑死在标签上,日后想改某块布局却找不到来源。更好的做法是用 Vue 组件封装重复 UI(比如做一个 MyButton.vue),既消除重复,又清晰可控。
29-7
本地字体文件建议放进 public/fonts 目录,再用 @font-face 在样式表里通过 /fonts/xxx.woff2 引用(public 目录的文件以根路径 / 直接可访问,下一章细讲)。
Nuxt 还内置了 PostCSS,默认就带了 autoprefixer(自动补厂商前缀)、cssnano(压缩)等,一般不用额外配置。如果你想加嵌套语法之类的插件,在 nuxt.config.ts 的 postcss 字段写即可:
export default defineNuxtConfig({
postcss: {
plugins: {
'postcss-nested': {},
},
},
})
29-8
这一章我们梳理了 Nuxt 样式的几块拼图:全站样式用 css 配置项或组件内 import;组件自己的样式用 <style scoped> 做隔离;需要变量和嵌套就上 SCSS 等预处理器;想快速出界面可以接 Tailwind。选哪种没有标准答案,小项目用 scoped 就够,团队追求一致性就上 Tailwind 或 UI 库。下一章我们聊样式之外的另一种资源——静态文件该怎么放。
29-7 样式方案的选型建议
面对这么多样式方案,怎么选?一个简单的决策框架:如果你熟悉 Tailwind CSS 并且团队认同原子化 CSS 的理念,首选 Tailwind,它和 Nuxt 的集成最成熟。如果团队更习惯传统 CSS 写法,用 SCSS 模块是稳妥的选择。如果项目对包体积非常敏感,UnoCSS 的按需生成更有优势。
无论选哪种方案,都要注意一个原则:不要混用多种样式方案。混用会增加构建复杂度、加大包体积,还会让团队成员困惑。在项目初期就确定方案并统一执行。
Nuxt 4 对 CSS 的处理做了进一步优化。构建工具 Vite 会自动处理 CSS 的提取、压缩和代码分割,你不需要额外配置。开发时修改样式文件,HMR 会即时反映到页面上,开发体验和各方案的原生工具基本一致。