SCSS 本身不能动态注入,所有 $variable 均在构建时静态替换为固定值;所谓“按需动态注入局部 CSS”,实为 dynamic import 触发构建工具提取关联 CSS chunk、配合 scoped 或 CSS-in-JS 隔离作用域、再由 JS 执行实际注入三者协作的结果。

SCSS 本身不能“动态注入”——它在构建时就编译完了,所有 $variable 都被替换成固定值;所谓“按需动态注入局部 CSS”,实际是组合三件事:用 dynamic import 加载组件、让构建工具自动提取关联 CSS、再靠 scoped 或 CSS-in-JS 机制隔离样式作用域。
dynamic import 触发的 CSS chunk 是怎么生成的
Webpack/Vite 会在你 import() 一个 JS 模块时,自动扫描其依赖图。如果该模块 @import './Button.scss' 或 style lang="scss" 中含样式,构建工具会把这部分 CSS 提取为独立 chunk,并在加载 JS 后自动插入 。
- 必须确保 SCSS 文件不是全局
@import到入口(如main.scss),否则它会被打进主包,失去“按需”意义 - Vue 中用
defineAsyncComponent、React 中用React.lazy,底层都依赖这个机制 - 检查最终产物:打开浏览器 DevTools → Network → 过滤
.css,切换路由时应看到新 CSS 文件加载
SCSS 局部化 ≠ scoped,但可以配合使用
scoped 是 Vue 的编译时属性标记(如 data-v-f3f2e1a4),而 SCSS 编译后只是普通 CSS;二者不冲突,但目标不同:前者防样式泄漏,后者管变量和嵌套。
- 在
<style lang="scss" scoped></style>中写$color: red;→ 编译后$color消失,只留color: red;,且带 scope 属性选择器 - 不要指望
$color能在运行时被 JS 修改——它早被替换了;真要动态,得用var(--color)+:root注入 - 若组件用
@use 'shared/vars' as v;,v.$primary仍只参与编译,不会生成可读取的 CSS 变量
真正“动态注入”的部分只能靠 JS 完成
比如主题切换时改 --theme-color,或 A/B 测试加载不同配色方案——这些必须绕过 SCSS 编译阶段,直接操作 DOM 或 CSSStyleSheet。
立即学习“前端免费学习笔记(深入)”;
- 用
document.createElement('style')+textContent写入规则,比引入styled-components更轻、更可控 - SCSS 可以帮你生成那串 CSS 字符串(例如用
@each循环输出.theme-dark { --bg: #111; }),但注入动作本身必须由 JS 执行 - 注意顺序:JS 注入的
<style></style>默认优先级高于普通 CSS,但若与!important冲突,或存在同名var()覆盖,结果可能不符合预期
最容易被忽略的是:SCSS 的“局部”只存在于源码组织层面,编译后它和手写的 CSS 没区别;所谓“动态注入局部 CSS”,本质是构建工具链 + 运行时 JS 的协作结果,而不是 SCSS 自身能力。别在 uni.scss 里写 #ifdef,也别试图用 @extend .#{$state}——那些地方根本不会被当作动态逻辑执行。


















