Sass是目前最流行的CSS预处理器之一,它提供了变量、嵌套、混入、函数等强大特性,能让样式代码更加模块化和易于维护。在Vue项目中使用Sass已经是非常普遍的做法,但由于构建工具版本差异和Sass本身的语言演进,实际接入过程中还是会踩到不少坑。本文将从安装配置、基本用法、常见问题三个层面,把vue项目中怎么使用sass这件事彻底讲明白。

一、安装与配置:Vue CLI和Vite两种情况分别处理
首先需要明确一点:Sass的编译工作由两部分共同完成,一个是sass(或早期的node-sass)编译核心,另一个是构建工具对应的加载器或插件。很多初学者只装了其中一个,导致样式一直编译不过去。
如果你的项目是基于Vue CLI(即使用vue.config.js的项目),需要安装sass和sass-loader两个包:
npm install sass sass-loader --save-dev
这里强烈建议直接使用sass而不是node-sass。因为node-sass依赖原生编译环境,在Windows上经常因为缺少Python或Visual Studio Build Tools而安装失败,而且官方已经将其标记为弃用状态。sass是Dart Sass的实现,纯JavaScript编写(也提供Dart原生版本),安装顺利且是官方推荐的主流选择。
如果你的项目是Vite创建的(比如Vue 3生态下的新项目),则更简单,只需要安装sass一个包,Vite内置了对Sass的支持,检测到依赖后自动启用:
npm install -D sass
安装完成后,在单文件组件中把<style>标签加上lang="scss"或lang="sass"即可:
<style lang="scss">
.box {
color: red;
.title {
font-size: 18px;
}
}
</style>这里要注意scss和sass的区别:SCSS语法使用大括号和分号,与原生CSS完全兼容,学习成本低;而Sass缩进式语法靠缩进表达层级,书写更快但团队协作时争议较大。绝大多数项目实际使用的都是SCSS语法,本文后续示例也以SCSS为主。
二、Sass在Vue组件中的核心用法
1. 变量定义与使用
变量是Sass最基础也最实用的功能。建议在src/styles目录下建立统一的变量文件,比如variables.scss,集中管理主题色、间距、字号等设计规范:
// src/styles/variables.scss $primary-color: #409eff; $danger-color: #f56c6c; $spacing-base: 8px; $font-size-large: 18px;
在组件中通过@use引入后即可使用:
<style lang="scss" scoped>
@use "@/styles/variables.scss" as vars;
.button {
background: vars.$primary-color;
padding: vars.$spacing-base * 2;
}
</style>2. 全局自动注入变量
如果每个组件都要手动@use一遍变量文件,写起来非常繁琐。这时可以利用构建工具的预处理配置,把变量文件自动注入到每个SCSS文件头部。Vue CLI项目的配置写在vue.config.js中:
// vue.config.js
module.exports = {
css: {
loaderOptions: {
scss: {
additionalData: `@use "@/styles/variables.scss" as *;`
}
}
}
}Vite项目的配置则写在vite.config.js里:
// vite.config.js
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/styles/variables.scss" as *;`
}
}
}
})配置好之后,任何组件里都可以直接使用$primary-color等变量,无需再手动导入。需要注意的是,旧版本配置项叫prependData,更早的时候叫data,如果你从网上抄的配置不生效,大概率是版本对不上,可以检查一下sass-loader的版本号再确定该用哪个字段。
3. 嵌套、混入与父选择器
嵌套写法让选择器结构和HTML结构保持一致,配合&符号可以引用父选择器:
.card {
padding: 16px;
&:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
&__title {
font-weight: bold;
}
.card-body & {
margin: 0;
}
}混入(mixin)适合封装需要复用的一段样式逻辑,比如文本溢出省略:
@mixin ellipsis($line: 1) {
overflow: hidden;
text-overflow: ellipsis;
@if $line == 1 {
white-space: nowrap;
} @else {
display: -webkit-box;
-webkit-line-clamp: $line;
-webkit-box-orient: vertical;
}
}
.text {
@include ellipsis(2);
}三、常见问题排查汇总
问题1:安装后报Module build failed错误
这类错误通常和sass-loader版本与webpack版本不匹配有关。Vue CLI 4对应webpack 4,应使用sass-loader@10;Vue CLI 5对应webpack 5,使用sass-loader@12及以上。如果报错信息里出现找不到某个loader选项,可以固定版本安装:
npm install sass-loader@10.5.2 sass --save-dev
问题2:变量在组件中找不到
排查思路分三步:第一,确认变量文件本身语法正确且变量名以$开头;第二,确认自动注入配置的字段名与构建工具版本匹配;第三,确认路径别名@指向的是src目录。另外,如果你使用的是新版Dart Sass,@import被标记为废弃,官方推荐改用@use,两者在作用域上有区别:@use引入的变量需要带命名空间访问,除非写成as *的形式。
问题3:scoped样式与Sass的关系
有些同学以为是Sass导致了scoped失效。实际上scoped属性和预处理器是两套独立机制,Sass只负责编译样式本身,scoped负责在编译后给选择器添加属性选择器以实现样式隔离。如果发现子组件内部元素样式不生效,那是scoped的隔离机制在起作用,与Sass无关,可以使用深度选择器::v-deep解决,Vue 3中写作:deep(.child-class)。
问题4:编译警告deprecation warning
升级到新版Dart Sass后,控制台可能出现大量关于@import或除法运算的弃用警告。前者按前面说的改用@use即可;后者是因为/作为除法运算符被弃用,应改用math.div()函数,并配合@use "sass:math";引入数学模块。
四、工程化实践建议
在中小型项目中,一个合理的Sass目录结构可以这样组织:src/styles下分出variables.scss(变量)、mixins.scss(混入)、reset.scss(样式重置)、index.scss(统一出口)。全局样式在main.js中引入一次,组件内的局部样式写在scoped的style块里,公共部分通过自动注入共享。
还要提醒一点,Sass的能力虽强,但不要过度使用。嵌套层级过深会让最终生成的选择器冗长且优先级混乱,一般建议嵌套不超过三层。对于简单的静态页面,原生CSS的自定义属性(CSS变量)配合现代特性已经够用,没必要为了用Sass而用Sass。根据项目规模选择合适的工具,才是工程化的正确打开方式。
vue sass配置sass使用vue cli修改时间:2026-09-04 23:06:49