在学完原生 CSS 之后,很多人都会接触到一个新名词:Sass / SCSS。
这时常见的疑惑通常有三个:
- 现代浏览器都已经这么强了,为什么项目里还会用 Sass?
- Vue 3 + Vite 项目里,
scss到底该怎么接? - 既然有 CSS 变量了,Sass 还有必要学吗?
这些问题都很正常。
因为 Sass 不是“替代 CSS 的另一门语言”,而是一个建立在 CSS 之上的样式工程化工具。它解决的不是“浏览器能不能识别某个属性”,而是:
- 样式是否更容易复用
- 变量、模块和设计规范是否更容易维护
- 大型项目里的样式组织是否足够清晰
如果你把 Vue 组件理解为“视图模块”,那么 Sass 更像是帮助你管理“样式模块”的工具。
本文就来系统讲清楚 Sass/SCSS 在 Vue 项目中的常用知识点、关键知识点,以及它和原生 CSS 变量之间到底该怎么取舍。
1. 先搞清楚:Sass、SCSS 到底是什么关系
很多初学者会把这两个词当成两个完全不同的技术,其实不是。
Sass 是这个预处理器的总称,而它有两种语法风格:
Sass缩进语法:不写大括号和分号SCSS语法:写法更接近普通 CSS,最常用
例如,下面是 Sass 缩进语法:
$primary-color: #409eff
.button
color: $primary-color
下面是 SCSS 语法:
$primary-color: #409eff;
.button {
color: $primary-color;
}
在现代 Vue 项目里,大家几乎都使用 SCSS,因为它更接近原生 CSS,迁移成本更低。
所以你在项目里看到:
<style lang="scss">
</style>
本质上就是在使用 Sass 的 SCSS 语法。
2. 为什么现代项目还会用 Sass
很多人会问:
现在原生 CSS 已经有变量、有嵌套趋势、有现代布局了,为什么还要 Sass?
答案是:
因为 Sass 解决的不只是“语法糖”,更是样式组织和工程化复用的问题。
2.1 Sass 最常见的价值
在真实项目里,Sass 最常见的用途主要有这些:
- 变量统一管理:品牌色、间距、圆角、阴影、字体大小集中维护
- 样式嵌套:让组件内部层级结构更清晰
- 混入复用:把重复样式逻辑抽成
mixin - 模块拆分:把全局变量、主题、函数、工具样式拆到独立文件
- 样式计算:比如对间距、颜色、尺寸进行组合和推导
2.2 最适合用 Sass 的场景
Sass 特别适合以下项目:
- 有统一设计规范的后台管理系统
- 有公共组件库的项目
- 页面较多、样式重复较多的中大型项目
- 需要做主题变量管理的业务系统
2.3 不要神化 Sass
Sass 很有用,但不是“用了就高级”。
它并不能自动解决:
- CSS 命名混乱
- 组件职责不清
- 样式污染
- 页面结构混乱
如果项目本身结构很乱,Sass 只会让“更复杂的混乱”变得更难维护。
所以真正专业的思路应该是:
先有清晰的样式组织规则,再用 Sass 来提高复用和维护效率。
3. 在 Vite 项目中接入 SCSS
3.1 安装依赖
如果你使用的是 Vue 3 + Vite 项目,接入 SCSS 非常简单。先安装 sass:
npm install -D sass
这里注意:
- 现在通常安装的是
sass - 不再推荐使用旧的
node-sass
装好之后,Vite 就能自动识别 .scss 文件和 <style lang="scss"> 语法。
3.2 在 Vue 单文件组件里使用
最常见的写法就是:
<template>
<button class="login-btn">登录</button>
</template>
<style scoped lang="scss">
.login-btn {
padding: 12px 20px;
border-radius: 8px;
background-color: #409eff;
color: #fff;
}
</style>
这说明两件事:
- 你仍然是在写组件样式
- 只是样式部分由普通 CSS 换成了 SCSS 能力
3.3 单独使用 .scss 文件
除了写在组件内部,你也可以把样式拆到独立文件中:
src/
├── styles/
│ ├── index.scss
│ ├── variables.scss
│ ├── mixins.scss
│ └── reset.scss
例如在 main.ts 中引入全局样式:
import { createApp } from 'vue'
import App from './App.vue'
import './styles/index.scss'
createApp(App).mount('#app')
这就是企业项目中更常见的用法。
4. 最常用的 SCSS 语法
下面这些,才是你在 Vue 项目里最常用、最应该掌握的内容。
4.1 变量:统一管理设计令牌
变量是 Sass 最经典的能力之一。
$primary-color: #409eff;
$danger-color: #f56c6c;
$border-radius-base: 8px;
$spacing-base: 16px;
.card {
padding: $spacing-base;
border-radius: $border-radius-base;
}
变量最常见的使用场景:
- 主色、成功色、危险色
- 间距体系
- 圆角体系
- 阴影值
- 字体尺寸
关键知识点:
变量不应该随便散落在业务组件里,而应该统一收敛到设计变量文件中管理。
4.2 嵌套:让样式层级更自然
SCSS 支持嵌套写法,这也是大家最直观能感受到的便利。
.user-card {
padding: 16px;
background: #fff;
.title {
font-size: 18px;
font-weight: bold;
}
.desc {
margin-top: 8px;
color: #666;
}
}
它非常适合写组件内部结构样式。
但这里有个非常重要的常见坑:
嵌套不要过深。
不推荐这样写:
.page {
.container {
.content {
.card {
.title {
color: #333;
}
}
}
}
}
原因是:
- 选择器层级太深
- 后期覆盖困难
- 可维护性迅速变差
一般来说,嵌套控制在 2 到 3 层以内更合适。
4.3 &:引用当前选择器
在写状态类和 BEM 风格命名时,& 非常顺手:
.button {
padding: 10px 16px;
&:hover {
opacity: 0.9;
}
&--primary {
background-color: #409eff;
color: #fff;
}
&--danger {
background-color: #f56c6c;
color: #fff;
}
}
这在组件封装里非常常见。
4.4 mixin:复用一段样式逻辑
如果一段样式要反复出现,而且还可能带参数,就很适合抽成 mixin。
@mixin flex-center($direction: row) {
display: flex;
flex-direction: $direction;
justify-content: center;
align-items: center;
}
.dialog-footer {
@include flex-center();
}
.empty-state {
@include flex-center(column);
}
mixin 非常适合:
- Flex 布局复用
- 文本省略
- 按钮样式模板
- 主题块样式复用
4.5 占位选择器 % 与 @extend
如果你想复用一套纯样式结构,也可以使用占位选择器:
%ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.title {
@extend %ellipsis;
}
.sub-title {
@extend %ellipsis;
}
不过在团队项目里,很多人更偏向于用 mixin,因为 @extend 在复杂选择器合并时有时不够直观。
所以你可以先记住一个经验:
- 通用样式逻辑复用:优先考虑
mixin - 简单静态样式复用:
@extend可以作为补充
5. @use 才是现代 Sass 的正确姿势
过去很多教程会写:
@import './variables.scss';
@import './mixins.scss';
但现在更推荐使用 @use。
5.1 为什么不再推荐 @import
因为旧版 @import 存在一些问题:
- 命名空间容易污染
- 重复导入时不够清晰
- 模块边界不明确
5.2 @use 的基本写法
例如我们有一个变量文件:
// styles/_variables.scss
$primary-color: #409eff;
$border-radius-base: 8px;
在组件样式中使用:
@use '@/styles/variables' as vars;
.login-btn {
background-color: vars.$primary-color;
border-radius: vars.$border-radius-base;
}
这里的 vars. 就是命名空间。
它的好处是:
- 变量来源更清晰
- 不容易和本地变量冲突
- 项目规模变大后更容易维护
5.3 @use ... as * 什么时候可以用
你也可以这样写:
@use '@/styles/variables' as *;
这样变量就可以直接使用,不需要命名空间前缀。
虽然写起来更短,但在大型项目里不建议滥用,因为它又会带来“全局污染”风险。
更稳妥的建议是:
- 小型项目可以适度用
as * - 中大型项目优先使用具名命名空间
这属于 Sass 里的关键知识点。
6. Vue 项目里的样式模块拆分方案
Sass 真正有价值的地方,不只是“能写变量”,而是你怎么组织样式文件。
6.1 一套常见的目录结构
src/
├── styles/
│ ├── index.scss # 全局入口
│ ├── reset.scss # 样式重置
│ ├── variables.scss # 设计变量
│ ├── mixins.scss # 混入
│ ├── functions.scss # Sass 函数
│ ├── common.scss # 通用类
│ └── theme.scss # 主题相关
一个简单的 index.scss 可以这样组织:
@use './reset';
@use './common';
而在组件内部需要变量和混入时,按需引入:
@use '@/styles/variables' as vars;
@use '@/styles/mixins' as mixins;
.page-title {
color: vars.$primary-color;
@include mixins.flex-center();
}
6.2 什么应该放全局,什么应该放组件内部
建议这样划分:
适合全局文件的内容:
- Reset / Normalize
- 设计变量
- 工具类
- 主题色
- 通用
mixin
适合组件内部的内容:
- 当前组件的结构样式
- 当前组件的状态样式
- 当前组件的局部覆盖样式
这个边界如果不分清,项目后期非常容易出现“样式到处都有,但谁都不敢删”的情况。
7. 在 Vue 单文件组件里怎么写更合理
7.1 scoped 和 scss 可以一起使用
最常见的写法是:
<style scoped lang="scss">
.user-panel {
padding: 16px;
.title {
font-size: 20px;
}
}
</style>
这表示:
- 使用 SCSS 编写样式
- 同时让样式限制在当前组件内
7.2 什么时候不加 scoped
以下场景常常不加 scoped:
- 全局样式文件
- 主题变量覆盖
- 第三方组件库样式覆盖
- 通用工具类样式
例如你要覆盖 Element Plus 某些全局变量时,就通常不会使用 scoped。
7.3 覆盖第三方组件样式时要注意什么
在 Vue 中,如果你使用了 scoped,有时需要借助深度选择器:
.user-form {
:deep(.el-input__wrapper) {
border-radius: 8px;
}
}
这类写法在整合 Element Plus 时很常见。
但也要注意:
- 不要把第三方组件库的覆盖样式写得过散
- 最好集中到页面级或主题级样式中管理
8. Sass 和原生 CSS 变量,到底怎么选
这应该是现代前端里最现实的问题之一。
因为现在浏览器已经支持 CSS 自定义属性:
:root {
--primary-color: #409eff;
}
.button {
background-color: var(--primary-color);
}
那为什么还要 Sass 变量?
答案是:
它们解决的问题并不完全一样。
8.1 Sass 变量更适合“编译期管理”
Sass 变量在构建时就会被替换掉。
它更适合:
- 管理静态设计令牌
- 做样式模块复用
- 写工具函数和
mixin - 做结构化样式组织
8.2 CSS 变量更适合“运行时切换”
CSS 变量最大的优势是:
它能在浏览器运行时动态变化。
它更适合:
- 深色模式切换
- 动态主题切换
- 用户自定义主题色
- JS 在运行时修改样式变量
例如:
:root {
--primary-color: #409eff;
}
[data-theme='dark'] {
--primary-color: #222;
}
8.3 最推荐的现实方案
在现代 Vue 项目里,一个非常实用的思路是:
- Sass 负责样式组织、模块拆分、混入和静态变量
- CSS 变量负责主题切换和运行时动态能力
这不是二选一,而是协作关系。
这也是本文最重要的关键知识点之一。
9. 常用知识点与关键知识点整理
为了帮助你快速建立体系,我们把 Sass 在 Vue 项目里的内容拆成两部分。
9.1 常用知识点
这些是你进入项目后最常碰到的:
- 安装
sass - 在 Vite 中使用
.scss - 在 Vue 组件里写
<style lang="scss"> - 变量
- 嵌套
&当前选择器引用mixin和@include- 样式文件拆分
9.2 关键知识点
这些决定你是不是“只会写语法”,还是“真的会做样式工程化”:
SCSS才是 Vue 项目里的主流写法- 变量要统一收敛,不要散落到处都是
- 嵌套不要过深
- 优先使用
@use,不要再依赖老式@import - Sass 变量和 CSS 变量不是互相替代关系
- 全局样式、组件样式、主题样式必须分层管理
如果你把这些点掌握了,Sass 才真正变成了项目能力,而不是一堆零散语法。
10. 常见坑与避坑建议
10.1 把 Sass 当成“高级 CSS 炫技工具”
有些人学了 Sass 之后,最喜欢做的事就是疯狂嵌套、疯狂抽象。
这会直接导致:
- 选择器层级爆炸
- 代码阅读困难
- 覆盖关系难以理解
记住:Sass 是为了降低复杂度,不是制造复杂度。
10.2 变量命名没有规范
不推荐:
$blue: #409eff;
$big-radius: 12px;
更推荐:
$color-primary: #409eff;
$radius-base: 8px;
变量命名最好体现“语义”,而不是只描述视觉颜色。
10.3 所有样式都写全局
如果项目一上来就把大量业务样式都写进全局 index.scss,后面很快就会失控。
建议始终坚持:
- 全局负责规则和基础能力
- 组件负责局部实现
10.4 继续使用过时的 @import
如果是新项目,尽量从一开始就使用 @use。
这样后面不会再经历一轮 Sass 模块化迁移。
11. 一个适合 Vue 后台项目的落地建议
如果你正在做一个 Vue 3 后台项目,我更推荐这样的搭配:
- 用
SCSS做变量、混入和模块拆分 - 用
scoped管理大部分组件局部样式 - 用少量全局样式文件管理 Reset、工具类和主题变量
- 用 CSS 变量承接深色模式或主题切换
- 对第三方组件库的覆盖集中管理,不要零散散落
这样做的好处是:
- 写起来顺手
- 结构清晰
- 组件边界明确
- 后续接入主题切换也比较顺
12. 总结
Sass/SCSS 在现代 Vue 项目里,价值并不只是“多几个语法糖”。
它真正的作用是帮助你把样式从“零散拼凑”升级成“可维护的工程结构”。
你至少应该掌握这些核心认知:
SCSS是 Vue 项目中的主流写法sass在 Vite 中接入很简单<style lang="scss">是最常见的组件写法- 变量、嵌套、
mixin、@use、模块拆分是高频能力 - Sass 更适合编译期管理,CSS 变量更适合运行时动态主题
如果你把这些点用在真实项目里,Sass 就不再只是“前端面试里提到过的技术名词”,而会真正变成你组织样式系统的一部分。