Vue3 使用 Sass/SCSS 预处理器指南

Marimo_z
2025-04-23 / 0 评论 / 85 阅读 / 正在检测是否收录...

1. 安装依赖

npm install -D sass-embedded

该包提供了最新版本的 Dart Sass 嵌入式编译器,性能优于传统 Ruby Sass 和部分 Node 版本。


2. 基础配置

Vue 单文件组件使用:

<style lang="scss">
/* 直接编写 SCSS 代码 */
</style>

全局样式配置(vue.config.js):

module.exports = {
  css: {
    loaderOptions: {
      scss: {
        // 全局注入变量/混合宏(适用于所有组件)
        additionalData: `@import "@/styles/global-vars.scss";`
      }
    }
  }
}

3. 基础使用示例

组件内使用:

<template>
  <div class="demo-box">
    <button class="styled-button">Click me</button>
  </div>
</template>

<style lang="scss" scoped>
// 局部变量
$primary-color: #42b983;
$border-radius: 8px;

.demo-box {
  padding: 2rem;
  background: lighten($primary-color, 45%);

  .styled-button {
    padding: 12px 24px;
    background: $primary-color;
    border-radius: $border-radius;
    
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 15px rgba($primary-color, 0.3);
    }
  }
}
</style>

4. 核心语法详解

1. 变量定义

$font-stack: Helvetica, sans-serif;
$primary-color: #333;
$spacing-unit: 1rem;

body {
  font: 100% $font-stack;
  color: $primary-color;
  margin: $spacing-unit * 2;
}

2. 嵌套规则

.navbar {
  background: #f8f9fa;
  
  ul {
    margin: 0;
    padding: 0;
    list-style: none;

    li {
      display: inline-block;
      
      a {
        padding: 0.5rem;
        &:hover {
          text-decoration: underline;
        }
      }
    }
  }
}

3. 混合宏 (Mixin)

// 定义
@mixin center-flex($direction: row) {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: $direction;
}

// 使用
.container {
  @include center-flex(column);
  min-height: 100vh;
}

4. 继承 (Extend)

%button-base {
  padding: 12px 24px;
  border-radius: 4px;
  font-size: 1rem;
}

.primary-button {
  @extend %button-base;
  background: #42b983;
  color: white;
}

.outline-button {
  @extend %button-base;
  border: 2px solid #42b983;
}

5. 模块化导入

// variables.scss
$breakpoint-md: 768px;

// mixins.scss
@mixin respond-to($breakpoint) {
  @media (min-width: $breakpoint) {
    @content;
  }
}

// main.scss
@use 'variables' as vars;
@use 'mixins';

.header {
  padding: 2rem;
  
  @include mixins.respond-to(vars.$breakpoint-md) {
    padding: 3rem;
  }
}

6. 运算与函数

$base-size: 16px;

.container {
  font-size: $base-size;
  width: 100% - 20%; // 80%
  height: calc(100vh - #{$base-size * 2});
  background: darken(#42b983, 10%);
}

7. 条件语句

@mixin theme-colors($theme) {
  @if $theme == 'dark' {
    background: #333;
    color: white;
  } @else if $theme == 'light' {
    background: #fff;
    color: #333;
  } @else {
    background: #f0f0f0;
  }
}

.theme-box {
  @include theme-colors('dark');
}

5. 最佳实践

  1. 文件组织:

    src/
      styles/
        ├── abstracts/
        │   ├── _variables.scss
        │   ├── _mixins.scss
        ├── components/
        │   ├── _buttons.scss
        ├── main.scss
  2. 变量命名:

    // 颜色
    $color-primary: #42b983;
    $color-danger: #ff4757;
    
    // 间距
    $spacing-sm: 0.5rem;
    $spacing-md: 1rem;
    
    // 响应式断点
    $breakpoint-md: 768px;
  3. 响应式处理:

    @mixin respond-to($breakpoint) {
      @media (min-width: $breakpoint) {
        @content;
      }
    }
    
    .card {
      width: 100%;
      
      @include respond-to($breakpoint-md) {
        width: 50%;
      }
    }

6. 常见问题排查

1. 样式未生效:

  • 检查 <style> 标签是否包含 lang="scss"
  • 确认变量/混合宏的作用域(全局注入需要配置)
  • 检查选择器嵌套是否正确

2. 安装后报错:

# 确保 package.json 包含
"devDependencies": {
  "sass-embedded": "^1.0.0"
}
  • 清除 node_modules 后重新安装
  • 检查与其他 sass 包的版本冲突

3. 全局变量无法使用:

// vue.config.js 正确配置
additionalData: `
  @import "@/styles/variables.scss";
  @import "@/styles/mixins.scss";
`
1

评论 (0)

取消