最直接方式是在nuxt.config.ts的css数组中写入CSS路径,如'~/assets/css/main.css'或'node_modules/normalize.css/normalize.css',Nuxt自动注入所有页面;路径须为字符串、支持别名、顺序决定优先级,禁用@import且需确保extractCSS启用。

在 nuxt.config.ts 里用 css 数组引入
最直接的方式是把 CSS 文件路径写进配置的 css 字段,Nuxt 会自动注入到所有页面。支持本地文件(如 ~/assets/css/main.css)和 node_modules 中的包(如 ~node_modules/normalize.css/normalize.css)。
注意路径必须是字符串,不能是对象或函数;如果用别名(~ 或 @),确保它已正确定义(默认 ~ 指向 src 目录)。
-
css数组里的样式会在<head>中作为<link>插入(SSR 时)或通过 JS 动态加载(SPA fallback),顺序即为数组顺序 - 不要在这里写
@import语句——那是 CSS 文件内部的事,不是配置项的用法 - 若引入的是预处理器文件(如
scss),需额外安装对应 loader(sass+sass-loader),且 Nuxt 会自动处理,但路径仍要写成~/assets/scss/main.scss
用 app.vue 的 <style> 标签全局注入
如果你的样式逻辑和应用生命周期强相关(比如依赖 definePageMeta 或需要响应式主题切换),或者想用 scoped 配合 :global 控制范围,可以放在 app.vue 的顶层 <style> 块里。
这种写法本质是把样式提升为“根组件样式”,会作用于整个应用,但要注意:它不会被提取为独立 CSS 文件(而是内联在 JS bundle 中),不利于缓存和首屏渲染优化。
立即学习“前端免费学习笔记(深入)”;
- 只适合少量、动态、或与 Vue 状态联动的样式(例如基于
useColorMode()切换的变量) - 写
:global(.btn) { ... }才能影响子组件,否则默认是 scoped 行为 - 避免在这里 import 大型 CSS 文件(如 Bootstrap),会导致 JS 包体积膨胀
避免在 pages/ 或 components/ 里重复 @import
有人习惯在每个 <style> 块开头写 @import "@/assets/css/base.css";,这会导致相同样式被多次解析、重复注入,可能引发 specificity 冲突或 FOUC(闪屏)。
Nuxt 的构建系统不合并重复的 @import,每个组件都会走一遍解析流程,哪怕路径完全一致。
- 一旦用了
css配置全局引入,就不要再手动@import同一文件 - 若某些组件需要额外样式,应单独建新文件(如
~/components/foo/Foo.module.css),而非复用全局入口 - 检查打包产物中是否出现多份
main.css内容——这是重复引入的典型信号
遇到 HMR 失效或样式未更新?先查 build.extractCSS
开发时改了全局 CSS 却没反应,大概率是构建配置干扰了热更新。Nuxt 3 默认启用 CSS 提取(extractCSS: true),但某些插件或自定义 webpack 配置会覆盖它。
确认你的 nuxt.config.ts 没有显式设 build: { extractCSS: false };如果用了 css: ['~/assets/css/main.css'] 却发现样式只在服务端生效、客户端空白,就是这个开关被关了。
- 保持
extractCSS: true(默认值)才能让全局 CSS 正确生成独立文件并由 Nuxt 自动注入 - 禁用后,CSS 会打到 JS 中,触发 Vue 的 runtime 注入逻辑,但 SSR 和 CSR 渲染路径不一致,容易漏样式
- 运行
nuxt build && nuxt preview测试真实环境行为,别只信 dev server
extractCSS 开关状态和 css 路径别名解析失败——这两点不报错,但样式就是不出现。


















