CSS也能用条件循环啦?一篇文章彻底掌握 SCSS 用法与 Vite+Vue3 集成实战
SCSS(Sassy CSS)作为 CSS 预处理器的主流方案,凭借变量、嵌套、混合器等特性大幅提升 CSS 开发效率。本文将从 SCSS 基础语法到进阶技巧,再到 Vite+Vue3 项目的完整集成流程,帮你彻底学会 SCSS 的使用。
一、SCSS 基础认知
1. 什么是 SCSS?
SCSS 是 Sass(Syntactically Awesome Style Sheets)的语法扩展,兼容 CSS 语法(后缀为.scss),可通过编译器转换为标准 CSS。相比原生 CSS,其核心优势在于:
- 支持变量存储(颜色、尺寸等复用)
- 嵌套语法(简化层级结构)
- 代码复用机制(混合器、继承)
- 逻辑控制能力(条件、循环)
2. 环境准备(单独使用 SCSS)
若需单独编译 SCSS 文件,需先安装编译工具:
# 全局安装sass(SCSS官方编译器)
npm install -g sass
# 编译SCSS文件:sass 输入文件 输出文件
sass src/style.scss dist/style.css
# 实时监听文件变化(开发模式)
sass --watch src/style.scss:dist/style.css
二、SCSS 核心语法(必学)
1. 变量(Variables)
用于存储重复使用的值(颜色、字体、尺寸等),使用$定义,支持作用域。
基础用法
// 定义变量(全局作用域)
$primary-color: #42b983; // Vue官方主题色
$font-size-base: 16px;
$border-radius: 4px;
// 使用变量
.button {
background: $primary-color;
font-size: $font-size-base;
border-radius: $border-radius;
}
// 局部变量(仅在嵌套块内生效)
.card {
$card-padding: 16px; // 局部变量
padding: $card-padding;
border: 1px solid #eee;
}
变量插值(字符串拼接)
用于拼接选择器、属性名或 URL:
$prefix: btn;
$attr: color;
.#{$prefix}-primary { // 拼接选择器
#{$attr}: $primary-color; // 拼接属性名
background: url("../images/#{$prefix}-bg.png"); // 拼接URL
}
2. 嵌套(Nesting)
简化 CSS 层级结构,避免重复书写父选择器,支持选择器嵌套、属性嵌套。
选择器嵌套
// SCSS
.nav {
width: 100%;
ul {
list-style: none;
display: flex;
}
li {
margin: 0 10px;
a {
color: #333;
&:hover { // & 表示父选择器(此处为a)
color: $primary-color;
}
}
}
}
// 编译后的CSS
.nav { width: 100%; }
.nav ul { list-style: none; display: flex; }
.nav li { margin: 0 10px; }
.nav li a { color: #333; }
.nav li a:hover { color: #42b983; }
属性嵌套(针对带前缀的属性)
// SCSS
.box {
font: { // 属性嵌套(font-*)
size: 14px;
weight: 500;
family: "Roboto", sans-serif;
}
border: { // border-*
width: 1px;
color: #ddd;
style: solid;
}
}
// 编译后的CSS
.box {
font-size: 14px;
font-weight: 500;
font-family: "Roboto", sans-serif;
border-width: 1px;
border-color: #ddd;
border-style: solid;
}
3. 混合器(Mixins)
用于复用代码块(支持参数),适合定义带逻辑的样式(如兼容性前缀、通用组件样式),使用@mixin定义,@include调用。
无参数混合器
// 定义混合器(清除浮动)
@mixin clear-fix {
&::after {
content: "";
display: table;
clear: both;
}
}
// 调用混合器
.header {
@include clear-fix;
height: 60px;
}
带参数混合器(支持默认值)
// 定义带参数的混合器(按钮样式)
@mixin button-style($bg: $primary-color, $text: #fff, $radius: $border-radius) {
background: $bg;
color: $text;
border-radius: $radius;
padding: 8px 16px;
border: none;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
// 调用(使用默认参数)
.btn-primary {
@include button-style;
}
// 调用(自定义参数)
.btn-danger {
@include button-style(#ff4444, #fff, 6px);
}
4. 继承(Extend)
用于复用选择器的样式(无参数),适合纯样式复用,使用@extend实现,编译后会合并选择器(比混合器更简洁)。
// 基础样式
.base-btn {
padding: 8px 16px;
border: none;
border-radius: $border-radius;
cursor: pointer;
}
// 继承基础样式并扩展
.btn-success {
@extend .base-btn;
background: #4caf50;
color: #fff;
}
.btn-warning {
@extend .base-btn;
background: #ffc107;
color: #333;
}
// 编译后的CSS(合并选择器)
.base-btn, .btn-success, .btn-warning {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn-success { background: #4caf50; color: #fff; }
.btn-warning { background: #ffc107; color: #333; }
三、SCSS 进阶特性
1. 函数(Functions)
SCSS 内置大量函数(颜色、数字、字符串等),也支持自定义函数(使用@function定义,@return返回值)。
常用内置函数
- 颜色函数:lighten()(提亮)、darken()(加深)、rgba()(透明色)
- 数字函数:round()(四舍五入)、ceil()(向上取整)、floor()(向下取整)
// 颜色函数示例
.button {
background: $primary-color;
&:hover {
background: lighten($primary-color, 10%); // 提亮10%
}
&:active {
background: darken($primary-color, 10%); // 加深10%
}
}
// 数字函数示例
.box {
width: round(100.6px); // 101px
height: ceil(200.1px); // 201px
}
自定义函数
// 自定义函数:px转rem(假设根字体16px)
@function px-to-rem($px) {
@return $px / 16px * 1rem;
}
// 使用
.container {
width: px-to-rem(1200px); // 75rem
padding: px-to-rem(24px); // 1.5rem
}
2. 指令(Directives)
条件判断(@if/@else if/@else)
@mixin text-size($size) {
@if $size == "small" {
font-size: 12px;
} @else if $size == "medium" {
font-size: 16px;
} @else {
font-size: 20px;
}
}
.text {
@include text-size("medium"); // 16px
}
循环(@for/@each)
- @for:按次数循环(from ... through包含终点,from ... to不包含终点)
// 生成1-5号字体样式
@for $i from 1 through 5 {
.text-#{$i} {
font-size: 12px + $i * 2px;
}
}
// 编译后
.text-1 { font-size: 14px; }
.text-2 { font-size: 16px; }
// ... 直到.text-5
- @each:遍历列表 / 映射
// 遍历列表
$colors: primary #42b983, danger #ff4444, success #4caf50;
@each $name, $color in $colors {
.bg-#{$name} {
background: $color;
}
}
// 遍历映射(类似对象)
$font-sizes: (
small: 12px,
medium: 16px,
large: 20px
);
@each $key, $value in $font-sizes {
.text-#{$key} {
font-size: $value;
}
}
3. 模块化(@import/@use/@forward)
SCSS 支持拆分文件(模块化),避免单文件过大。Vite+Vue3 项目中推荐使用@use(Sass 1.23.0+,替代旧版@import)。
目录结构示例
src/
├── styles/
│ ├── _variables.scss // 变量(下划线开头表示“局部文件”,不单独编译)
│ ├── _mixins.scss // 混合器
│ └── main.scss // 主文件(引入其他模块)
@use 用法(推荐)
// main.scss 中引入其他模块
@use "./variables" as vars; // 别名vars(可选,默认用文件名)
@use "./mixins";
// 使用模块中的变量和混合器
.body {
background: vars.$primary-color; // 通过别名访问变量
font-size: vars.$font-size-base;
}
.button {
@include mixins.button-style(); // 访问混合器
}
@forward 用法(批量导出模块)
若需统一导出多个子模块,可创建_index.scss:
// styles/_index.scss
@forward "./variables"; // 导出variables模块
@forward "./mixins"; // 导出mixins模块
// 其他文件中只需引入_index.scss
@use "./styles" as styles;
.button {
background: styles.$primary-color;
@include styles.button-style();
}
四、Vite+Vue3 中引入 SCSS(核心实战)
Vite 内置 SCSS 支持,无需额外安装编译器,只需简单配置即可在 Vue3 项目中使用。
1. 项目初始化(若未创建项目)
# 创建Vue3项目(选择Default模板)
npm create vite@latest my-vue3-scss -- --template vue
# 进入项目目录
cd my-vue3-scss
# 安装依赖
npm install
2. 安装 SCSS 依赖
Vite 需要sass依赖(SCSS 编译器),安装即可:
npm install sass -D
3. 两种引入方式(局部 / 全局)
方式 1:单文件组件(SFC)局部引入
在 Vue 组件的<style>标签中添加lang="scss",直接使用 SCSS 语法,或引入外部 SCSS 文件。
<!-- src/components/HelloSCSS.vue -->
<template>
<div class="hello-scss">
<h2 class="title">SCSS局部引入示例</h2>
<button class="custom-btn">点击按钮</button>
</div>
</template>
<script setup></script>
<style lang="scss">
// 1. 直接写SCSS(变量、嵌套)
$title-color: #333;
$btn-bg: #42b983;
.hello-scss {
padding: 20px;
.title {
color: $title-color;
font-size: 18px;
}
.custom-btn {
background: $btn-bg;
color: #fff;
padding: 8px 16px;
border: none;
border-radius: 4px;
&:hover {
opacity: 0.9;
}
}
}
// 2. 引入外部SCSS文件(局部生效)
// @import "../styles/_mixins.scss";
// .another-btn {
// @include button-style(#ff4444);
// }
</style>
方式 2:全局引入(全局变量 / 混合器)
若需在所有组件中直接使用全局变量(如主题色),无需每个组件单独引入,可通过 Vite 配置全局注入。
步骤 1:创建全局 SCSS 文件
// src/styles/_variables.scss(全局变量)
$primary-color: #42b983;
$font-size-base: 16px;
$border-radius: 4px;
// src/styles/_mixins.scss(全局混合器)
@mixin button-style($bg: $primary-color, $text: #fff) {
background: $bg;
color: $text;
padding: 8px 16px;
border: none;
border-radius: $border-radius;
}
步骤 2:配置 Vite(vite.config.js)
通过css.preprocessorOptions.scss.additionalData注入全局 SCSS 代码:
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path' // 需引入path模块(Node内置)
export default defineConfig({
plugins: [vue()],
resolve: {
// 配置路径别名(@指向src)
alias: {
'@': path.resolve(__dirname, 'src')
}
},
css: {
preprocessorOptions: {
scss: {
// 注入全局变量和混合器(分号分隔多个文件)
additionalData: `
@use "@/styles/_variables.scss" as *;
@use "@/styles/_mixins.scss" as *;
`
// 注:as * 表示不使用别名,直接访问变量(如$primary-color)
}
}
}
})
步骤 3:在组件中直接使用全局 SCSS
无需引入文件,直接使用全局变量和混合器:
<!-- src/components/GlobalSCSS.vue -->
<template>
<button class="global-btn">全局SCSS按钮</button>
</template>
<script setup></script>
<style lang="scss">
.global-btn {
// 直接使用全局变量和混合器
@include button-style($primary-color, #fff);
font-size: $font-size-base;
margin-top: 10px;
}
</style>
4. 实战:用 SCSS 写响应式布局
结合 SCSS 变量和混合器,快速实现响应式适配:
<template>
<div class="responsive-container">
<div class="card">响应式卡片</div>
</div>
</template>
<script setup></script>
<style lang="scss">
// 定义响应式断点变量(全局变量可放_global.scss)
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
);
// 自定义响应式混合器
@mixin responsive($breakpoint) {
$width: map-get($breakpoints, $breakpoint);
@media (min-width: $width) {
@content; // 插入使用时的样式
}
}
.responsive-container {
width: 90%;
margin: 0 auto;
// 使用响应式混合器
@include responsive(sm) {
width: 95%;
}
@include responsive(md) {
width: 80%;
}
@include responsive(lg) {
width: 70%;
}
.card {
padding: 16px;
background: #f5f5f5;
@include responsive(md) {
padding: 24px;
border-radius: $border-radius;
}
}
}
</style>
五、常见问题与最佳实践
1. 常见问题
- 问题 1:全局样式不生效?
检查 Vite 配置中additionalData的文件路径是否正确(推荐用@别名),且需重启 Vite 服务(配置修改后需重启)。
- 问题 2:SCSS 语法报错(如 “Undefined variable”)?
确认变量已定义且引入正确,若使用@use需通过别名访问(如vars.$color),或加as *省略别名。
- 问题 3:Vite 安装 sass 后仍报错?
尝试删除node_modules和package-lock.json,重新执行npm install,确保sass版本与 Vite 兼容(推荐sass@1.60.0+)。
2. 最佳实践
- 模块化拆分:按功能拆分 SCSS 文件(变量、混合器、组件样式、全局样式),避免单文件冗余。
- 命名规范:变量名用kebab-case(如$font-size-base),混合器名用camelCase(如@mixin buttonStyle)。
- 避免过度嵌套:嵌套层级不超过 3 层(防止编译后 CSS 选择器过长,影响性能)。
- 优先用@use替代@import:@use支持作用域隔离,避免变量污染,是 Sass 官方推荐的模块化方案。
- 全局样式管理:全局样式(如重置样式、主题色)放在src/styles/目录,通过 Vite 全局注入,组件样式写在 SFC 的<style lang="scss">中。
六、总结
SCSS 的核心价值在于 “提升 CSS 复用性与可维护性”,通过变量、嵌套、混合器等特性简化开发;而在 Vite+Vue3 中,只需安装sass并配置全局注入,即可无缝集成 SCSS。建议从实战出发,先在小组件中尝试变量和嵌套,再逐步使用混合器、模块化等进阶特性,最终形成符合项目需求的 SCSS 开发规范。
若需进一步优化 SCSS 工作流,可结合 CSS Modules(避免样式冲突)或 CSS-in-JS 方案,但 SCSS 作为基础预处理器,仍是 Vue3 项目中样式管理的首选方案之一。
更多推荐
所有评论(0)