设计规范 精选推荐

设计系统建立完整指南:从零到一构建企业级设计基础设施

HTMLPAGE 团队
20 分钟阅读

系统讲解如何从零开始建立企业级设计系统,涵盖设计原则制定、设计令牌定义、组件库架构、文档体系、版本管理等核心环节,助力团队高效协作。

#设计系统 #组件库 #设计令牌 #UI规范 #团队协作

设计系统建立完整指南:从零到一构建企业级设计基础设施

设计系统是现代产品开发的基础设施。它不仅是一套组件库,更是一种工作方式、一套标准、一个生态系统。本文将详细讲解如何从零开始构建一套完整的企业级设计系统。

什么是设计系统

设计系统的定义

设计系统是一套完整的标准集合,包含设计原则、视觉语言、组件库、模式库和最佳实践,用于指导产品的设计和开发。

┌─────────────────────────────────────────────────────────────┐
│                       设计系统金字塔                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│                    ┌───────────────┐                        │
│                    │    产品体验    │  ← 最终用户感知        │
│                    └───────────────┘                        │
│                  ┌───────────────────┐                      │
│                  │    页面模板      │  ← 页面级布局模式      │
│                  └───────────────────┘                      │
│                ┌───────────────────────┐                    │
│                │     组件 & 模式       │  ← 可复用 UI 单元   │
│                └───────────────────────┘                    │
│              ┌───────────────────────────┐                  │
│              │       设计令牌           │  ← 原子级变量      │
│              └───────────────────────────┘                  │
│            ┌───────────────────────────────┐                │
│            │        设计原则              │  ← 指导思想      │
│            └───────────────────────────────┘                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

设计系统 vs 组件库 vs 风格指南

概念内容用途
风格指南颜色、字体、间距等视觉规范保持视觉一致性
组件库可复用的 UI 组件代码提高开发效率
设计系统原则 + 规范 + 组件 + 模式 + 文档 + 工具全方位产品设计基础设施

建立设计系统的价值

对设计团队

  • 减少重复设计工作 80%+
  • 统一设计语言,新成员快速上手
  • 更多时间聚焦创新和用户体验

对开发团队

  • 组件复用率提升,开发效率翻倍
  • 减少设计沟通成本
  • 代码更加规范和可维护

对产品团队

  • 产品体验一致性保障
  • 快速迭代,缩短上市时间
  • 降低设计和开发债务

对企业

  • 品牌形象统一
  • 跨团队协作效率提升
  • 长期成本节约

设计原则制定

设计原则是设计系统的灵魂,指导所有设计决策。

制定原则的方法

1. 从品牌价值观出发

品牌价值观          →          设计原则
───────────────────────────────────────────
可靠、专业         →          简洁、克制
创新、年轻         →          大胆、活力
亲和、温暖         →          圆润、柔和
高效、智能         →          直接、智能

2. 从用户需求出发

用户需求           →          设计原则
───────────────────────────────────────────
快速完成任务       →          效率优先
减少学习成本       →          直观易懂
信任和安全感       →          可预测、一致
无障碍使用         →          包容性设计

原则的结构

好的设计原则应该:

  • 可操作:能够指导具体决策
  • 有区分度:不是放之四海而皆准的废话
  • 易记忆:数量控制在 5-7 条
# Example: ABC 公司设计原则

## 1. 清晰优先 (Clarity First)
信息的清晰传达是最重要的。在装饰性和功能性之间,永远选择功能性。
- ✓ 使用明确的标签和说明
- ✓ 减少视觉噪音
- ✗ 为了美观牺牲可读性

## 2. 一致而非统一 (Consistent, Not Uniform)
保持核心体验的一致性,但允许根据上下文做出适当调整。
- ✓ 相同操作相同行为
- ✓ 考虑场景差异
- ✗ 机械地应用所有规则

## 3. 渐进式披露 (Progressive Disclosure)
先展示必要信息,高级选项按需展开。
- ✓ 默认展示 20% 覆盖 80% 用户
- ✓ 复杂功能分层展示
- ✗ 一次性堆砌所有选项

## 4. 包容性设计 (Inclusive Design)
为所有用户设计,包括能力不同的用户。
- ✓ 符合 WCAG 2.1 AA 标准
- ✓ 支持键盘和屏幕阅读器
- ✗ 只考虑主流用户

## 5. 性能即体验 (Performance is UX)
加载速度和响应性是用户体验的一部分。
- ✓ 组件轻量化
- ✓ 考虑弱网络环境
- ✗ 引入重型动效库

设计令牌体系

设计令牌(Design Tokens)是设计系统的原子级变量。

令牌的层级结构

┌─────────────────────────────────────────────────────────────┐
│                     设计令牌层级                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Global Tokens (全局令牌)                                   │
│  ├─ $color-blue-500: #3B82F6                               │
│  ├─ $color-gray-100: #F3F4F6                               │
│  └─ $spacing-4: 16px                                       │
│                                                             │
│        ↓ 引用                                               │
│                                                             │
│  Alias Tokens (语义令牌)                                    │
│  ├─ $color-primary: $color-blue-500                        │
│  ├─ $color-background: $color-gray-100                     │
│  └─ $spacing-component: $spacing-4                         │
│                                                             │
│        ↓ 引用                                               │
│                                                             │
│  Component Tokens (组件令牌)                                │
│  ├─ $button-bg-primary: $color-primary                     │
│  ├─ $button-padding: $spacing-component                    │
│  └─ $card-background: $color-background                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

定义令牌规范

// tokens/base.json - 基础色板
{
  "color": {
    "gray": {
      "50":  { "value": "#F9FAFB", "type": "color" },
      "100": { "value": "#F3F4F6", "type": "color" },
      "200": { "value": "#E5E7EB", "type": "color" },
      "300": { "value": "#D1D5DB", "type": "color" },
      "400": { "value": "#9CA3AF", "type": "color" },
      "500": { "value": "#6B7280", "type": "color" },
      "600": { "value": "#4B5563", "type": "color" },
      "700": { "value": "#374151", "type": "color" },
      "800": { "value": "#1F2937", "type": "color" },
      "900": { "value": "#111827", "type": "color" }
    },
    "blue": {
      "50":  { "value": "#EFF6FF", "type": "color" },
      "100": { "value": "#DBEAFE", "type": "color" },
      "500": { "value": "#3B82F6", "type": "color" },
      "600": { "value": "#2563EB", "type": "color" },
      "700": { "value": "#1D4ED8", "type": "color" }
    }
  },
  "spacing": {
    "0":  { "value": "0", "type": "dimension" },
    "1":  { "value": "4px", "type": "dimension" },
    "2":  { "value": "8px", "type": "dimension" },
    "3":  { "value": "12px", "type": "dimension" },
    "4":  { "value": "16px", "type": "dimension" },
    "5":  { "value": "20px", "type": "dimension" },
    "6":  { "value": "24px", "type": "dimension" },
    "8":  { "value": "32px", "type": "dimension" },
    "10": { "value": "40px", "type": "dimension" },
    "12": { "value": "48px", "type": "dimension" }
  },
  "borderRadius": {
    "none": { "value": "0", "type": "dimension" },
    "sm":   { "value": "4px", "type": "dimension" },
    "md":   { "value": "6px", "type": "dimension" },
    "lg":   { "value": "8px", "type": "dimension" },
    "xl":   { "value": "12px", "type": "dimension" },
    "full": { "value": "9999px", "type": "dimension" }
  }
}
// tokens/semantic.json - 语义令牌
{
  "color": {
    "text": {
      "primary":   { "value": "{color.gray.900}", "type": "color" },
      "secondary": { "value": "{color.gray.600}", "type": "color" },
      "disabled":  { "value": "{color.gray.400}", "type": "color" },
      "inverse":   { "value": "{color.gray.50}", "type": "color" }
    },
    "background": {
      "primary":   { "value": "#FFFFFF", "type": "color" },
      "secondary": { "value": "{color.gray.50}", "type": "color" },
      "elevated":  { "value": "#FFFFFF", "type": "color" }
    },
    "border": {
      "default":  { "value": "{color.gray.200}", "type": "color" },
      "focus":    { "value": "{color.blue.500}", "type": "color" }
    },
    "action": {
      "primary":        { "value": "{color.blue.500}", "type": "color" },
      "primaryHover":   { "value": "{color.blue.600}", "type": "color" },
      "primaryActive":  { "value": "{color.blue.700}", "type": "color" }
    }
  }
}

令牌到代码的转换

使用 Style Dictionary 将令牌转换为多平台代码:

// style-dictionary.config.js
const StyleDictionary = require('style-dictionary');

StyleDictionary.registerTransform({
  name: 'size/pxToRem',
  type: 'value',
  matcher: (token) => token.type === 'dimension',
  transformer: (token) => {
    const px = parseFloat(token.value);
    return `${px / 16}rem`;
  }
});

module.exports = {
  source: ['tokens/**/*.json'],
  platforms: {
    // CSS 变量
    css: {
      transformGroup: 'css',
      buildPath: 'build/css/',
      files: [{
        destination: 'variables.css',
        format: 'css/variables'
      }]
    },
    
    // SCSS 变量
    scss: {
      transformGroup: 'scss',
      buildPath: 'build/scss/',
      files: [{
        destination: '_variables.scss',
        format: 'scss/variables'
      }]
    },
    
    // JavaScript 对象
    js: {
      transformGroup: 'js',
      buildPath: 'build/js/',
      files: [{
        destination: 'tokens.js',
        format: 'javascript/es6'
      }]
    },
    
    // TypeScript
    ts: {
      transformGroup: 'js',
      buildPath: 'build/ts/',
      files: [{
        destination: 'tokens.ts',
        format: 'javascript/es6'
      }]
    }
  }
};

生成的输出:

/* build/css/variables.css */
:root {
  --color-gray-50: #F9FAFB;
  --color-gray-100: #F3F4F6;
  --color-text-primary: var(--color-gray-900);
  --color-text-secondary: var(--color-gray-600);
  --color-action-primary: var(--color-blue-500);
  --spacing-4: 1rem;
  --border-radius-md: 0.375rem;
}
// build/ts/tokens.ts
export const tokens = {
  color: {
    gray: {
      50: '#F9FAFB',
      100: '#F3F4F6',
      // ...
    },
    text: {
      primary: '#111827',
      secondary: '#4B5563',
    }
  },
  spacing: {
    4: '1rem',
    // ...
  }
} as const;

组件库架构

组件分类体系

┌─────────────────────────────────────────────────────────────┐
│                      组件分类                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  基础组件 (Primitives)                                      │
│  └─ 最底层、无业务逻辑的原子组件                             │
│     ├─ Button, Icon, Input, Text, Box                       │
│     └─ 可被任何上层组件使用                                  │
│                                                             │
│  通用组件 (Common)                                          │
│  └─ 常见的 UI 模式,跨业务通用                               │
│     ├─ Card, Modal, Dropdown, Tabs, Toast                   │
│     └─ 由基础组件组合而成                                    │
│                                                             │
│  业务组件 (Business)                                        │
│  └─ 特定业务场景的复合组件                                   │
│     ├─ UserCard, ProductTile, CommentBox                    │
│     └─ 包含业务逻辑和数据结构                                │
│                                                             │
│  布局组件 (Layout)                                          │
│  └─ 控制页面结构和响应式布局                                 │
│     ├─ Container, Grid, Stack, Sidebar                      │
│     └─ 处理间距、对齐、响应式断点                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

组件设计原则

1. 单一职责

// ✗ 职责过多的组件
<UserCard 
  user={user}
  showFollowButton
  showMessageButton
  showStats
  layout="horizontal"
  theme="dark"
/>

// ✓ 拆分为多个单一职责组件
<Card>
  <UserAvatar user={user} />
  <UserInfo user={user} />
  <UserActions>
    <FollowButton userId={user.id} />
    <MessageButton userId={user.id} />
  </UserActions>
</Card>

2. 组合优于配置

// ✗ 通过 props 配置一切
<Button 
  icon="plus" 
  iconPosition="left"
  loading={isLoading}
  loadingText="保存中..."
  size="lg"
  variant="primary"
/>

// ✓ 通过组合实现灵活性
<Button size="lg" variant="primary">
  {isLoading ? (
    <>
      <Spinner size="sm" />
      <span>保存中...</span>
    </>
  ) : (
    <>
      <Icon name="plus" />
      <span>新建</span>
    </>
  )}
</Button>

3. 样式与行为分离

// Button.tsx - 组件逻辑
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, ...props }, ref) => {
    return (
      <button
        ref={ref}
        className={cn(buttonVariants({ variant, size }), className)}
        {...props}
      />
    );
  }
);

// Button.styles.ts - 样式定义
import { cva } from 'class-variance-authority';

export const buttonVariants = cva(
  'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2',
  {
    variants: {
      variant: {
        primary: 'bg-primary text-white hover:bg-primary-hover',
        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary-hover',
        outline: 'border border-input bg-transparent hover:bg-accent',
      },
      size: {
        sm: 'h-8 px-3 text-sm',
        md: 'h-10 px-4 text-sm',
        lg: 'h-12 px-6 text-base',
      },
    },
    defaultVariants: {
      variant: 'primary',
      size: 'md',
    },
  }
);

组件 API 设计规范

// 组件 Props 设计规范

// 1. 使用语义化的 prop 名称
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  // ✗ 避免使用 type(与 HTML 属性冲突)
  // ✗ 避免使用缩写 var, sz
}

// 2. 布尔 props 使用正面语义
interface InputProps {
  disabled?: boolean;     // ✓ 默认 false
  readOnly?: boolean;     // ✓ 默认 false
  // ✗ enabled?: boolean; // 避免双重否定
}

// 3. 事件处理器使用 on 前缀
interface ModalProps {
  onClose?: () => void;           // ✓
  onOpenChange?: (open: boolean) => void; // ✓
  // ✗ closeHandler, handleClose
}

// 4. 支持 className 和 style 覆盖
interface CardProps {
  className?: string;
  style?: React.CSSProperties;
  // 允许用户自定义样式
}

// 5. 使用 children 而非 text props
interface BadgeProps {
  children: React.ReactNode;  // ✓
  // ✗ text?: string;
  // ✗ label?: string;
}

// 6. 提供合理的默认值
interface TooltipProps {
  placement?: 'top' | 'bottom' | 'left' | 'right'; // 默认 'top'
  delay?: number; // 默认 200
  // 默认值在组件内部设置
}

文档体系

文档的组成

设计系统文档
├── 入门指南
│   ├── 快速开始
│   ├── 安装与配置
│   └── 设计原则
│
├── 设计基础
│   ├── 颜色系统
│   ├── 字体排版
│   ├── 间距与网格
│   ├── 图标系统
│   └── 动效规范
│
├── 组件文档
│   ├── 组件概览
│   └── 各组件详情
│       ├── 描述与用途
│       ├── 交互示例
│       ├── API 参考
│       ├── 设计指南
│       └── 可访问性
│
├── 模式库
│   ├── 表单模式
│   ├── 导航模式
│   ├── 数据展示
│   └── 反馈与提示
│
└── 资源与工具
    ├── Figma 资源
    ├── 品牌资产
    └── 贡献指南

组件文档模板

# Button 按钮

按钮用于触发操作或事件,如提交表单、打开对话框或执行功能。

## 何时使用

- 当用户需要触发一个动作时
- 当需要在页面上突出一个关键操作时

## 基础用法

<ComponentDemo>
  <Button>默认按钮</Button>
  <Button variant="secondary">次要按钮</Button>
  <Button variant="outline">描边按钮</Button>
</ComponentDemo>

## 变体

### 主要按钮 (Primary)
用于页面最重要的操作,一个页面通常只有一个主要按钮。

### 次要按钮 (Secondary)
用于次要操作,与主要按钮配合使用。

### 危险按钮 (Danger)
用于删除、移除等破坏性操作。

## 尺寸

<ComponentDemo>
  <Button size="sm">小号</Button>
  <Button size="md">中号</Button>
  <Button size="lg">大号</Button>
</ComponentDemo>

## 状态

### 禁用状态
<ComponentDemo>
  <Button disabled>禁用按钮</Button>
</ComponentDemo>

### 加载状态
<ComponentDemo>
  <Button loading>加载中</Button>
</ComponentDemo>

## API

| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| variant | 'primary' \| 'secondary' \| 'outline' \| 'ghost' \| 'danger' | 'primary' | 按钮变体 |
| size | 'sm' \| 'md' \| 'lg' | 'md' | 按钮尺寸 |
| disabled | boolean | false | 是否禁用 |
| loading | boolean | false | 是否加载中 |

## 可访问性

- 使用语义化的 `<button>` 元素
- 禁用状态有明确的视觉区分
- 支持键盘操作(Enter/Space 触发)
- 聚焦状态有清晰的视觉反馈

## 设计规范

- 按钮文案使用动词或动词短语
- 文案长度建议 2-6 个字符
- 同一区域内按钮尺寸保持一致
- 主要按钮放在操作区域的右侧或底部

使用 Storybook 构建交互式文档

// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Components/Button',
  component: Button,
  parameters: {
    layout: 'centered',
    docs: {
      description: {
        component: '按钮用于触发操作或事件。',
      },
    },
  },
  tags: ['autodocs'],
  argTypes: {
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'outline', 'ghost', 'danger'],
      description: '按钮的视觉变体',
    },
    size: {
      control: 'radio',
      options: ['sm', 'md', 'lg'],
      description: '按钮的尺寸',
    },
    disabled: {
      control: 'boolean',
      description: '是否禁用',
    },
    loading: {
      control: 'boolean',
      description: '是否显示加载状态',
    },
  },
};

export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = {
  args: {
    children: '主要按钮',
    variant: 'primary',
  },
};

export const Secondary: Story = {
  args: {
    children: '次要按钮',
    variant: 'secondary',
  },
};

export const AllVariants: Story = {
  render: () => (
    <div className="flex gap-4">
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="danger">Danger</Button>
    </div>
  ),
};

export const Sizes: Story = {
  render: () => (
    <div className="flex items-center gap-4">
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
    </div>
  ),
};

export const States: Story = {
  render: () => (
    <div className="flex gap-4">
      <Button>Default</Button>
      <Button disabled>Disabled</Button>
      <Button loading>Loading</Button>
    </div>
  ),
};

版本管理与发布

语义化版本控制

版本号格式:MAJOR.MINOR.PATCH

MAJOR (主版本)
└─ 不兼容的 API 变更
   例:组件 props 重命名、移除组件

MINOR (次版本)
└─ 向后兼容的功能新增
   例:新增组件、新增 props

PATCH (补丁版本)
└─ 向后兼容的问题修复
   例:样式修复、bug 修复

变更日志规范

# Changelog

## [2.1.0] - 2024-12-25

### ✨ New Features
- **Button**: 新增 `loading` 状态和 `loadingText` 属性
- **Modal**: 新增 `size` 属性,支持 sm/md/lg/xl 四种尺寸

### 🐛 Bug Fixes
- **Input**: 修复 disabled 状态下仍可聚焦的问题
- **Dropdown**: 修复在移动端点击外部无法关闭的问题

### 💄 Styles
- **全局**: 调整主色调从 #3B82F6 到 #2563EB
- **Button**: 优化 hover 状态的过渡动画

### ⚠️ Deprecations
- **Alert**: `type` 属性已废弃,请使用 `variant`

## [2.0.0] - 2024-12-01

### 💥 Breaking Changes
- **Button**: `type` 属性重命名为 `variant`
- **Icon**: 移除 `size` 属性,改用 CSS 控制尺寸
- **tokens**: 颜色令牌命名从 camelCase 改为 kebab-case

发布流程

# 1. 创建发布分支
git checkout -b release/2.1.0

# 2. 更新版本号
npm version minor

# 3. 更新 CHANGELOG
# 手动编辑 CHANGELOG.md

# 4. 构建并测试
npm run build
npm run test
npm run test:visual

# 5. 发布到 npm
npm publish

# 6. 合并到 main
git checkout main
git merge release/2.1.0

# 7. 打标签
git tag v2.1.0
git push origin v2.1.0

# 8. 发布文档
npm run deploy:docs

团队协作流程

组件贡献流程

┌────────────────────────────────────────────────────────────────┐
│                      组件贡献流程                               │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  1. 提案阶段                                                   │
│  ├─ 提交 RFC(组件设计提案)                                   │
│  ├─ 团队评审(设计 + 开发)                                    │
│  └─ 确定 API 和设计规范                                        │
│                                                                │
│  2. 设计阶段                                                   │
│  ├─ 设计师在 Figma 中创建组件                                  │
│  ├─ 设计评审                                                   │
│  └─ 交付设计规范文档                                           │
│                                                                │
│  3. 开发阶段                                                   │
│  ├─ 实现组件代码                                               │
│  ├─ 编写单元测试                                               │
│  ├─ 编写 Storybook stories                                     │
│  └─ 代码评审                                                   │
│                                                                │
│  4. 文档阶段                                                   │
│  ├─ 编写使用文档                                               │
│  ├─ 添加示例代码                                               │
│  └─ 更新 CHANGELOG                                             │
│                                                                │
│  5. 发布阶段                                                   │
│  ├─ QA 验收                                                    │
│  ├─ 发布新版本                                                 │
│  └─ 通知用户更新                                               │
│                                                                │
└────────────────────────────────────────────────────────────────┘

设计与开发同步

Figma (设计)                    代码 (开发)
─────────────────────────────────────────────
                                
设计令牌                        tokens/
  ├─ Colors                     ├─ colors.json
  ├─ Typography                 ├─ typography.json
  └─ Spacing                    └─ spacing.json
        │                              │
        ▼                              ▼
   Tokens Studio              Style Dictionary
   (Figma 插件)               (构建工具)
        │                              │
        └──────── 同步 ────────────────┘
                    │
                    ▼
              自动化 CI/CD
              检测变更并更新

总结

建立一个成功的设计系统需要:

  1. 明确的设计原则:指导所有设计决策
  2. 完善的令牌体系:确保视觉一致性
  3. 高质量的组件库:可复用、可组合、可访问
  4. 详尽的文档:降低使用门槛
  5. 规范的版本管理:平滑升级体验
  6. 顺畅的协作流程:设计与开发高效同步

设计系统是一个持续演进的产品,需要长期投入和维护。

延伸阅读