用 @mixin 封装带参数的尺寸/间距逻辑(如 size-scale)、状态样式(如 interactive-states)和 @function 处理主题色变体,配合 @use + with 实现可配置、低耦合的样式复用,避免硬编码、全局污染与响应式嵌套。

用 @mixin 封装可配置的尺寸/间距逻辑,别写死像素值
组件复用度低,常因为样式“长在”具体数值上——比如一个按钮固定写 padding: 12px 24px,换到卡片里就撑不开。Sass 的 @mixin 能把这类逻辑抽出来,让调用方决定“多大才算合适”。
常见错误是只封装静态样式,比如:@mixin btn-base { color: #333; } ——这没解决复用痛点。真正有用的是带参数的混合宏:
@mixin size-scale($scale: 1) {
padding: calc(8px * $scale) calc(16px * $scale);
font-size: calc(14px * $scale);
}
- 调用时传
$scale: 0.75得到紧凑版,$scale: 1.25得到放大版,组件本身不绑定具体尺寸 - 避免用
rem或em直接替代——它们依赖上下文字体大小,而calc()+ 变量更可控 - 注意编译后 CSS 不支持运行时缩放,所以
$scale必须是编译期已知值(不能是 CSS 自定义属性)
用 @mixin 统一状态样式,但别把交互逻辑也塞进去
很多组件的 :hover、:disabled 样式散落在各处,改一处漏三处。用混合宏统一管理状态样式是对的,但容易误把 JS 行为判断也加进来,比如试图用 @if $has-js 控制是否生成 :focus 规则——这行不通。
正确做法是只管样式输出,状态触发交给 HTML 类名或伪类:
@mixin interactive-states($hover-bg: #eee, $disabled-opacity: 0.5) {
&:hover { background-color: $hover-bg; }
&:active { transform: scale(0.98); }
&[disabled] { opacity: $disabled-opacity; pointer-events: none; }
}
- 所有状态都基于现有选择器扩展,不新增 class 名,避免 JS 和 CSS 状态不同步
- 禁用态用
[disabled]属性选择器,比.is-disabled更可靠(原生表单元素天然支持) - 别在 mixin 里写
@media嵌套响应式逻辑——它会让调用点不可预测;响应式应由组件外层容器控制
用 @function 处理颜色变体,避开硬编码色值
一个组件要支持 primary / success / warning 几种主题色,最差做法是每个颜色写一套 class:.btn-primary、.btn-success…… 这导致 CSS 体积膨胀,且新增主题要改多处。
用函数动态生成颜色变体,配合 mixin 注入,能大幅减少重复:
@function theme-color($type) {
@return map-get((primary: #007bff, success: #28a745, warning: #ffc107), $type);
}
<p>@mixin themed-border($type) {
border-color: theme-color($type);
}</p>
- 调用
@include themed-border(primary)即可生成对应边框,无需预设所有组合 - map 数据结构比一堆独立变量更易维护,新增主题只需改 map,不用动函数逻辑
- 注意 Sass 3.3+ 才支持
map-get,旧项目若用 Ruby Sass 3.2 需降级为全局变量 +@if判断
导出 mixin 时用 @use + with 配置,别靠 @import 全局污染
老项目常用 @import "_mixins" 把所有 mixin 拉进来,结果组件 A 改了 $border-radius,组件 B 的圆角全变了——这不是复用,是耦合。
Sass 模块系统要求显式导入和配置:
// _button.scss
@use 'mixins' with (
$base-radius: 6px,
$transition-speed: 0.2s
);
<p>.button {
@include mixins.size-scale(1);
@include mixins.interactive-states();
}</p>
-
@use是模块化前提,with让每个使用者独立配置,互不干扰 - 禁止在 mixin 文件里定义全局变量(如
$spacing-unit: 8px),所有可配置项必须通过with显式传入 - 如果团队还在用 Webpack + sass-loader 旧版本(implementation: require('sass'),否则
@use会报错
真正难的不是写几个 @mixin,而是让每个组件开发者习惯“先想配置项,再写样式”。一旦默认把尺寸、颜色、状态都做成参数,复用就从体力活变成自然结果。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











