全局CSS必须在main.ts中import才能生效,因为App.vue的<style>仅作用于当前组件且不参与构建流程;CSS中的@import不解析别名,需用预处理器注入变量;scoped组件需::v-deep穿透或抽离原子类到独立base.css。

全局 CSS 文件必须在 main.ts(或 main.js)中显式导入,否则不会进入构建流程,也不会影响任何组件。
为什么在 App.vue 里写 <style> 不算“全局”
Vue 编译器会把 <style> 块当作该组件的样式处理,即使没加 scoped,它也只作用于当前 SFC 的 template 节点,且不参与构建时的 CSS 合并。更关键的是:它无法被 PostCSS、PurgeCSS 或 Tailwind 的 content 扫描机制识别——比如你在 App.vue 里写了 .btn,但 tailwind.config.js 的 content 没包含 .vue 文件,@tailwind utilities 就压根不会生成 .btn 对应的规则。
- 真正全局生效的前提是:该 CSS 文件被 JS 入口直接
import,从而进入 Webpack/Vite 的依赖图 -
App.vue中的<style>属于组件级资源,和import './xxx.css'的语义完全不同 - 如果误以为它“全局”,后续用
scoped组件时会发现类名失效、权重被压制、甚至被 PurgeCSS 删掉
main.ts 导入路径写错导致样式不加载
Vite 默认支持 @/ 别名,但仅限于 JS/TS 模块解析;CSS 文件里的 @import(如 @import '@/styles/reset.css')默认不走别名解析,会报 File to import not found。所以全局 CSS 的导入必须在 JS 层完成,不能靠 CSS 内部 @import 拆分。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- ✅ 正确:在
main.ts顶部写import '@/styles/global.css' - ❌ 错误:在
global.css里写@import '@/styles/variables.css'(Vite 不解析 CSS 中的@/) - 若需复用变量,改用预处理器(如 SCSS),并通过
css.preprocessorOptions.scss.additionalData注入,而非纯 CSS@import
Scoped 组件里用不到全局类?不是没引入,是选择器没匹配上
写了 <style scoped> 的组件,Vue 会给所有选择器自动加上属性哈希(如 .btn[data-v-f3f3f3f3]),而你在 global.css 里定义的 .btn 没这个属性,自然不生效。
立即学习“前端免费学习笔记(深入)”;
- 不要关掉
scoped来“解决”,那会破坏样式隔离 - 要用
::v-deep(.btn)精准穿透(注意括号和选择器必须一起写) - 更推荐做法:把真正需要复用的原子类(
.text-sm、.flex、.bg-red-500)抽到独立的base.css,并在main.ts中import;同时确保这些类不在任何scoped块里被覆盖 - Tailwind 用户尤其注意:
@tailwind utilities必须和base、components在同一个 CSS 文件里,且该文件必须被main.ts直接导入
最易忽略的一点:全局 CSS 文件里如果写了顶层选择器(比如 body { margin: 0 }),在 Vite + Vue 3 中可能被 scoped 组件样式权重压制——因为编译后 scoped 规则带属性选择器,权重更高。真要重置,优先用 @layer base 或确保它在构建链最前端加载。

















