好的,我现在需要回答用户关于如何使用SCSS + BEM + 设计token进行管理的问题。首先,我需要回忆这三个概念的特点以及如何结合使用。

首先,设计token(Design Tokens)是设计系统中的基础变量,比如颜色、字体大小、间距等,通常用变量表示。SCSS支持变量,可以方便地管理这些token。然后,BEM(Block Element Modifier)是一种CSS命名规范,用于提高类名的可维护性和复用性。结合SCSS的嵌套和混合器(mixin)可以更好地实现BEM结构。

接下来,我需要考虑如何将这三者结合。首先,设计token应该放在SCSS的变量文件中,比如variables.scss,定义颜色、字体、间距等。然后,使用SCSS的嵌套语法来组织BEM的块(Block)、元素(Element)和修饰符(Modifier),确保类名符合BEM规范。同时,可以利用SCSS的mixin来复用BEM结构,减少重复代码。

然后,我需要具体说明步骤:

  1. 设计token管理:创建基础变量文件,定义颜色、字体、间距等全局token,可能还需要分主题的变量。
  2. BEM结构组织:使用SCSS的嵌套来编写BEM的块、元素和修饰符,确保类名结构清晰。
  3. 复用与维护:通过mixin或函数封装常用的BEM模式,结合设计token,提高代码复用性。

需要注意的点包括:避免过度嵌套导致的选择器权重问题,保持BEM类名的清晰,以及设计token的合理分类(如基础、组件、主题等)。

现在,我需要将这些思路整理成用户易懂的步骤,并给出示例代码,比如变量文件的结构、BEM类的SCSS写法,以及如何使用mixin来简化代码。同时,要确保示例符合用户项目中的SCSS使用习惯,比如用户项目中已经有@/assets/scss/variables.scss,可以参考这个路径。

使用 SCSS + BEM + 设计 Token 进行样式管理时,可以通过以下步骤实现规范化和可维护的样式系统:

一、设计 Token 管理(基础层)

设计 Token 是设计系统的原子化变量(如颜色、字体、间距等),需集中管理以便全局复用和主题切换。建议按类型分类存储在 SCSS 变量文件中。

1. 创建 Token 文件

在项目的 @/assets/scss/ 目录下创建 tokens 子目录,存放不同类型的设计 Token:

// 颜色 Token(基础色、品牌色、状态色等)
$color-primary: #2563eb; // 主色
$color-primary-light: #eff6ff; // 主色浅版
$color-success: #22c55e; // 成功色
$color-error: #ef4444; // 错误色
// 字体 Token(字号、字重、行高)
$font-size-base: 14px;
$font-size-lg: 16px;
$font-weight-medium: 500;
$line-height-base: 1.5;
// 间距 Token(边距、内边距)
$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 16px;
$spacing-lg: 24px;

2. 全局引入 Token

vite.config.js 中配置 SCSS 全局注入(用户项目已有类似配置),确保所有 SCSS 文件可直接使用 Token:

css: {
  preprocessorOptions: {
    scss: {
      additionalData: `
        @import "@/assets/scss/tokens/_colors.scss";
        @import "@/assets/scss/tokens/_typography.scss";
        @import "@/assets/scss/tokens/_spacing.scss";
      `
    }
  }
}

二、BEM 规范与 SCSS 结合(结构层)

BEM(Block-Element-Modifier)通过明确的命名规则解决 CSS 作用域混乱问题,SCSS 的嵌套语法可高效实现 BEM 结构。

1. BEM 命名规则

  • Block(块):独立组件,如 cardbutton,类名用 - 连接(或项目统一的分隔符)。
  • Element(元素):块的子元素,用 __ 连接块名,如 card__title
  • Modifier(修饰符):状态或变体,用 -- 连接块/元素名,如 card--disabledbutton__icon--large

2. SCSS 实现 BEM

利用 SCSS 的嵌套语法,按 BEM 结构编写样式,同时复用设计 Token:

// Block: card
.card {
  padding: $spacing-md; // 使用间距 Token
  border: 1px solid $color-primary-light; // 使用颜色 Token
  border-radius: 8px;
 
  // Element: card__title
  &__title {
    font-size: $font-size-lg; // 使用字体 Token
    font-weight: $font-weight-medium;
    color: $color-primary; // 使用颜色 Token
  }
 
  // Modifier: card--disabled(禁用状态)
  &--disabled {
    opacity: 0.6;
    cursor: not-allowed;
 
    // 嵌套 Element 的修饰符
    &__title {
      color: $color-text-disabled; // 假设已定义的 Token
    }
  }
}

三、高阶复用与维护(优化层)

通过 SCSS 的 mixinfunction 封装常用模式,减少重复代码,同时保持 BEM 规范。

1. 封装 BEM Mixin

定义通用 BEM Mixin,简化嵌套写法(可选,根据团队习惯):

@mixin bem($block) {
  .#{$block} {
    $current-block: $block;
    @content;
  }
 
  // 子元素嵌套
  @mixin element($element) {
    &__#{$element} {
      $current-element: $element;
      @content;
    }
  }
 
  // 修饰符嵌套
  @mixin modifier($modifier) {
    &--#{$modifier} {
      @content;
    }
  }
}

2. 使用 Mixin 编写 BEM

@include bem('button') {
  padding: $spacing-sm $spacing-md;
  border-radius: 4px;
 
  @include element('icon') {
    margin-right: $spacing-sm;
    font-size: $font-size-base;
  }
 
  @include modifier('primary') {
    background: $color-primary;
    color: white;
 
    @include element('icon') {
      color: white; // 覆盖图标颜色
    }
  }
}

四、注意事项

  1. 避免深度嵌套:SCSS 嵌套层级不超过 3 层(如 .block__element--modifier),防止 CSS 选择器权重过高。
  2. 主题切换:设计 Token 可结合 CSS 变量(var())实现动态主题,SCSS 预处理阶段生成基础样式,运行时通过 JS 切换变量值。
  3. 文档化:维护 Token 列表和 BEM 规范文档(如用 Style Dictionary 工具),确保团队协作一致性。

通过以上方式,SCSS 负责样式预处理和逻辑复用,BEM 保证类名规范和作用域清晰,设计 Token 实现原子化设计系统,三者结合可显著提升样式代码的可维护性和扩展性。