7.1 组件化开发概述

7.1.1 什么是组件化开发

组件化开发是一种将 UI 拆分为独立、可复用的代码片段的开发方法。每个组件封装了自己的结构、样式和行为,可以在应用程序的不同部分重复使用。

7.1.2 组件化的优势

  1. 可复用性:一次编写,多处使用
  2. 可维护性:集中管理,易于修改
  3. 一致性:确保 UI 的统一性
  4. 开发效率:减少重复代码
  5. 团队协作:便于分工合作

7.1.3 Tailwind CSS 中的组件化方法

在 Tailwind CSS 中,我们可以通过以下方式实现组件化:

  • HTML 模板组件
  • CSS 组件类
  • JavaScript 框架组件(React、Vue、Angular 等)
  • Web Components

7.2 使用 @apply 指令创建组件类

7.2.1 @apply 指令基础

@apply 指令允许我们将 Tailwind 的工具类组合成自定义的 CSS 类:

/* styles.css */
.btn {
  @apply px-4 py-2 rounded font-medium focus:outline-none focus:ring-2 focus:ring-offset-2;
}

.btn-primary {
  @apply bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500;
}

.btn-secondary {
  @apply bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500;
}

.btn-success {
  @apply bg-green-600 text-white hover:bg-green-700 focus:ring-green-500;
}

.btn-danger {
  @apply bg-red-600 text-white hover:bg-red-700 focus:ring-red-500;
}

7.2.2 按钮组件示例

<!-- 使用组件类 -->
<button class="btn btn-primary">主要按钮</button>
<button class="btn btn-secondary">次要按钮</button>
<button class="btn btn-success">成功按钮</button>
<button class="btn btn-danger">危险按钮</button>

<!-- 不同尺寸的按钮 -->
<style>
.btn-sm {
  @apply px-3 py-1.5 text-sm;
}

.btn-lg {
  @apply px-6 py-3 text-lg;
}

.btn-xl {
  @apply px-8 py-4 text-xl;
}
</style>

<button class="btn btn-primary btn-sm">小按钮</button>
<button class="btn btn-primary">默认按钮</button>
<button class="btn btn-primary btn-lg">大按钮</button>
<button class="btn btn-primary btn-xl">超大按钮</button>

7.2.3 卡片组件示例

/* 基础卡片 */
.card {
  @apply bg-white rounded-lg shadow-md overflow-hidden;
}

.card-header {
  @apply px-6 py-4 border-b border-gray-200;
}

.card-body {
  @apply px-6 py-4;
}

.card-footer {
  @apply px-6 py-4 bg-gray-50 border-t border-gray-200;
}

/* 卡片变体 */
.card-elevated {
  @apply shadow-lg hover:shadow-xl transition-shadow duration-300;
}

.card-bordered {
  @apply border border-gray-200 shadow-sm;
}

.card-flat {
  @apply shadow-none border border-gray-200;
}
<!-- 基础卡片 -->
<div class="card">
  <div class="card-header">
    <h3 class="text-lg font-semibold text-gray-900">卡片标题</h3>
  </div>
  <div class="card-body">
    <p class="text-gray-600">这是卡片的内容区域,可以包含任何类型的内容。</p>
  </div>
  <div class="card-footer">
    <button class="btn btn-primary">操作按钮</button>
  </div>
</div>

<!-- 高级卡片 -->
<div class="card card-elevated">
  <div class="card-body">
    <h3 class="text-xl font-bold text-gray-900 mb-2">产品名称</h3>
    <p class="text-gray-600 mb-4">产品描述信息...</p>
    <div class="flex justify-between items-center">
      <span class="text-2xl font-bold text-blue-600">¥299</span>
      <button class="btn btn-primary">立即购买</button>
    </div>
  </div>
</div>

7.3 表单组件库

7.3.1 输入框组件

/* 基础输入框 */
.form-input {
  @apply w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent;
}

.form-input-sm {
  @apply px-2 py-1 text-sm;
}

.form-input-lg {
  @apply px-4 py-3 text-lg;
}

/* 输入框状态 */
.form-input-error {
  @apply border-red-500 focus:ring-red-500;
}

.form-input-success {
  @apply border-green-500 focus:ring-green-500;
}

/* 标签 */
.form-label {
  @apply block text-sm font-medium text-gray-700 mb-1;
}

.form-label-required::after {
  content: ' *';
  @apply text-red-500;
}

/* 帮助文本 */
.form-help {
  @apply text-sm text-gray-500 mt-1;
}

.form-error {
  @apply text-sm text-red-600 mt-1;
}

/* 表单组 */
.form-group {
  @apply mb-4;
}
<!-- 基础表单组件 -->
<div class="form-group">
  <label for="email" class="form-label form-label-required">邮箱地址</label>
  <input type="email" id="email" class="form-input" placeholder="请输入邮箱地址">
  <p class="form-help">我们不会与任何人分享您的邮箱地址</p>
</div>

<!-- 错误状态 -->
<div class="form-group">
  <label for="password" class="form-label form-label-required">密码</label>
  <input type="password" id="password" class="form-input form-input-error" placeholder="请输入密码">
  <p class="form-error">密码长度至少为 8 个字符</p>
</div>

<!-- 成功状态 -->
<div class="form-group">
  <label for="username" class="form-label">用户名</label>
  <input type="text" id="username" class="form-input form-input-success" placeholder="请输入用户名">
  <p class="form-help text-green-600">用户名可用</p>
</div>

7.3.2 选择框组件

/* 选择框 */
.form-select {
  @apply w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white;
}

/* 复选框和单选框 */
.form-checkbox,
.form-radio {
  @apply w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500;
}

.form-radio {
  @apply rounded-full;
}

.form-check {
  @apply flex items-center;
}

.form-check-label {
  @apply ml-2 text-sm text-gray-700;
}

.form-check-group {
  @apply space-y-2;
}
<!-- 选择框 -->
<div class="form-group">
  <label for="country" class="form-label">国家/地区</label>
  <select id="country" class="form-select">
    <option value="">请选择国家/地区</option>
    <option value="cn">中国</option>
    <option value="us">美国</option>
    <option value="jp">日本</option>
  </select>
</div>

<!-- 复选框组 -->
<div class="form-group">
  <label class="form-label">兴趣爱好</label>
  <div class="form-check-group">
    <div class="form-check">
      <input type="checkbox" id="reading" class="form-checkbox">
      <label for="reading" class="form-check-label">阅读</label>
    </div>
    <div class="form-check">
      <input type="checkbox" id="music" class="form-checkbox">
      <label for="music" class="form-check-label">音乐</label>
    </div>
    <div class="form-check">
      <input type="checkbox" id="sports" class="form-checkbox">
      <label for="sports" class="form-check-label">运动</label>
    </div>
  </div>
</div>

<!-- 单选框组 -->
<div class="form-group">
  <label class="form-label">性别</label>
  <div class="form-check-group">
    <div class="form-check">
      <input type="radio" id="male" name="gender" class="form-radio">
      <label for="male" class="form-check-label">男</label>
    </div>
    <div class="form-check">
      <input type="radio" id="female" name="gender" class="form-radio">
      <label for="female" class="form-check-label">女</label>
    </div>
  </div>
</div>

7.4 导航组件库

7.4.1 导航栏组件

/* 基础导航栏 */
.navbar {
  @apply bg-white shadow-sm border-b border-gray-200;
}

.navbar-container {
  @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
}

.navbar-content {
  @apply flex justify-between items-center h-16;
}

.navbar-brand {
  @apply flex items-center;
}

.navbar-logo {
  @apply w-8 h-8 mr-3;
}

.navbar-title {
  @apply text-xl font-bold text-gray-900;
}

.navbar-nav {
  @apply hidden md:flex items-center space-x-8;
}

.navbar-link {
  @apply text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium transition-colors;
}

.navbar-link-active {
  @apply text-blue-600 bg-blue-50;
}

.navbar-toggle {
  @apply md:hidden text-gray-600 hover:text-blue-600;
}
<!-- 导航栏组件 -->
<nav class="navbar">
  <div class="navbar-container">
    <div class="navbar-content">
      <!-- 品牌 -->
      <div class="navbar-brand">
        <div class="navbar-logo bg-blue-600 rounded"></div>
        <span class="navbar-title">品牌名</span>
      </div>
      
      <!-- 导航链接 -->
      <div class="navbar-nav">
        <a href="#" class="navbar-link navbar-link-active">首页</a>
        <a href="#" class="navbar-link">产品</a>
        <a href="#" class="navbar-link">服务</a>
        <a href="#" class="navbar-link">关于</a>
        <button class="btn btn-primary">联系我们</button>
      </div>
      
      <!-- 移动端菜单按钮 -->
      <button class="navbar-toggle">
        <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
        </svg>
      </button>
    </div>
  </div>
</nav>

7.4.2 面包屑组件

.breadcrumb {
  @apply flex items-center space-x-2 text-sm text-gray-500;
}

.breadcrumb-item {
  @apply flex items-center;
}

.breadcrumb-link {
  @apply hover:text-blue-600 transition-colors;
}

.breadcrumb-current {
  @apply text-gray-900 font-medium;
}

.breadcrumb-separator {
  @apply mx-2 text-gray-400;
}
<!-- 面包屑组件 -->
<nav class="breadcrumb">
  <div class="breadcrumb-item">
    <a href="#" class="breadcrumb-link">首页</a>
  </div>
  <div class="breadcrumb-separator">/</div>
  <div class="breadcrumb-item">
    <a href="#" class="breadcrumb-link">产品</a>
  </div>
  <div class="breadcrumb-separator">/</div>
  <div class="breadcrumb-item">
    <span class="breadcrumb-current">详情</span>
  </div>
</nav>

7.4.3 标签页组件

.tabs {
  @apply border-b border-gray-200;
}

.tabs-nav {
  @apply flex space-x-8;
}

.tabs-tab {
  @apply py-2 px-1 border-b-2 border-transparent text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 transition-colors;
}

.tabs-tab-active {
  @apply border-blue-500 text-blue-600;
}

.tabs-content {
  @apply py-4;
}

.tabs-panel {
  @apply hidden;
}

.tabs-panel-active {
  @apply block;
}
<!-- 标签页组件 -->
<div class="tabs">
  <nav class="tabs-nav">
    <button class="tabs-tab tabs-tab-active">概述</button>
    <button class="tabs-tab">规格</button>
    <button class="tabs-tab">评价</button>
    <button class="tabs-tab">支持</button>
  </nav>
</div>

<div class="tabs-content">
  <div class="tabs-panel tabs-panel-active">
    <h3 class="text-lg font-semibold mb-2">产品概述</h3>
    <p class="text-gray-600">这里是产品的详细概述信息...</p>
  </div>
  <div class="tabs-panel">
    <h3 class="text-lg font-semibold mb-2">技术规格</h3>
    <p class="text-gray-600">这里是产品的技术规格信息...</p>
  </div>
  <div class="tabs-panel">
    <h3 class="text-lg font-semibold mb-2">用户评价</h3>
    <p class="text-gray-600">这里是用户评价信息...</p>
  </div>
  <div class="tabs-panel">
    <h3 class="text-lg font-semibold mb-2">技术支持</h3>
    <p class="text-gray-600">这里是技术支持信息...</p>
  </div>
</div>

7.5 反馈组件库

7.5.1 警告框组件

/* 基础警告框 */
.alert {
  @apply p-4 rounded-md border;
}

.alert-info {
  @apply bg-blue-50 border-blue-200 text-blue-800;
}

.alert-success {
  @apply bg-green-50 border-green-200 text-green-800;
}

.alert-warning {
  @apply bg-yellow-50 border-yellow-200 text-yellow-800;
}

.alert-error {
  @apply bg-red-50 border-red-200 text-red-800;
}

.alert-title {
  @apply font-medium mb-1;
}

.alert-description {
  @apply text-sm opacity-90;
}

.alert-close {
  @apply float-right text-lg leading-none cursor-pointer opacity-50 hover:opacity-75;
}
<!-- 警告框组件 -->
<div class="alert alert-info">
  <button class="alert-close">&times;</button>
  <div class="alert-title">信息提示</div>
  <div class="alert-description">这是一条信息提示消息。</div>
</div>

<div class="alert alert-success">
  <div class="alert-title">操作成功</div>
  <div class="alert-description">您的操作已成功完成。</div>
</div>

<div class="alert alert-warning">
  <div class="alert-title">注意</div>
  <div class="alert-description">请注意这个重要信息。</div>
</div>

<div class="alert alert-error">
  <div class="alert-title">错误</div>
  <div class="alert-description">操作失败,请重试。</div>
</div>

7.5.2 徽章组件

.badge {
  @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
}

.badge-primary {
  @apply bg-blue-100 text-blue-800;
}

.badge-secondary {
  @apply bg-gray-100 text-gray-800;
}

.badge-success {
  @apply bg-green-100 text-green-800;
}

.badge-warning {
  @apply bg-yellow-100 text-yellow-800;
}

.badge-danger {
  @apply bg-red-100 text-red-800;
}

.badge-lg {
  @apply px-3 py-1 text-sm;
}

.badge-dot {
  @apply w-2 h-2 rounded-full mr-1.5;
}
<!-- 徽章组件 -->
<span class="badge badge-primary">新功能</span>
<span class="badge badge-success">已完成</span>
<span class="badge badge-warning">待处理</span>
<span class="badge badge-danger">紧急</span>

<!-- 带点的徽章 -->
<span class="badge badge-primary">
  <span class="badge-dot bg-blue-400"></span>
  在线
</span>

<!-- 大尺寸徽章 -->
<span class="badge badge-success badge-lg">推荐</span>

7.5.3 进度条组件

.progress {
  @apply w-full bg-gray-200 rounded-full overflow-hidden;
}

.progress-bar {
  @apply h-2 bg-blue-600 transition-all duration-300 ease-out;
}

.progress-sm .progress-bar {
  @apply h-1;
}

.progress-lg .progress-bar {
  @apply h-4;
}

.progress-bar-success {
  @apply bg-green-600;
}

.progress-bar-warning {
  @apply bg-yellow-600;
}

.progress-bar-danger {
  @apply bg-red-600;
}

.progress-label {
  @apply text-sm text-gray-600 mb-1;
}

.progress-percentage {
  @apply text-sm text-gray-600 float-right;
}
<!-- 进度条组件 -->
<div class="mb-4">
  <div class="progress-label">
    项目进度
    <span class="progress-percentage">75%</span>
  </div>
  <div class="progress">
    <div class="progress-bar" style="width: 75%"></div>
  </div>
</div>

<!-- 不同颜色的进度条 -->
<div class="mb-4">
  <div class="progress-label">成功进度</div>
  <div class="progress">
    <div class="progress-bar progress-bar-success" style="width: 90%"></div>
  </div>
</div>

<div class="mb-4">
  <div class="progress-label">警告进度</div>
  <div class="progress">
    <div class="progress-bar progress-bar-warning" style="width: 60%"></div>
  </div>
</div>

<!-- 不同尺寸的进度条 -->
<div class="mb-4">
  <div class="progress-label">小进度条</div>
  <div class="progress progress-sm">
    <div class="progress-bar" style="width: 45%"></div>
  </div>
</div>

<div class="mb-4">
  <div class="progress-label">大进度条</div>
  <div class="progress progress-lg">
    <div class="progress-bar" style="width: 80%"></div>
  </div>
</div>

7.6 布局组件库

7.6.1 容器组件

.container-fluid {
  @apply w-full px-4 sm:px-6 lg:px-8;
}

.container-sm {
  @apply max-w-sm mx-auto px-4;
}

.container-md {
  @apply max-w-md mx-auto px-4;
}

.container-lg {
  @apply max-w-lg mx-auto px-4;
}

.container-xl {
  @apply max-w-xl mx-auto px-4;
}

.container-2xl {
  @apply max-w-2xl mx-auto px-4;
}

.container-full {
  @apply max-w-full mx-auto px-4;
}

7.6.2 网格组件

.grid-container {
  @apply grid gap-4;
}

.grid-cols-auto {
  @apply grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4;
}

.grid-cols-responsive {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

.grid-item {
  @apply bg-white rounded-lg shadow-sm p-4;
}

7.6.3 分隔符组件

.divider {
  @apply border-t border-gray-200 my-4;
}

.divider-vertical {
  @apply border-l border-gray-200 mx-4 h-full;
}

.divider-text {
  @apply relative flex justify-center my-4;
}

.divider-text::before {
  content: '';
  @apply absolute top-1/2 left-0 right-0 border-t border-gray-200;
}

.divider-text span {
  @apply bg-white px-4 text-sm text-gray-500;
}
<!-- 分隔符组件 -->
<div class="divider"></div>

<div class="divider-text">
  <span>或者</span>
</div>

<!-- 垂直分隔符 -->
<div class="flex items-center h-12">
  <span>左侧内容</span>
  <div class="divider-vertical"></div>
  <span>右侧内容</span>
</div>

7.7 实践案例:构建组件库

7.7.1 创建组件库结构

components/
├── base/
│   ├── buttons.css
│   ├── forms.css
│   └── typography.css
├── layout/
│   ├── containers.css
│   ├── grid.css
│   └── dividers.css
├── navigation/
│   ├── navbar.css
│   ├── breadcrumb.css
│   └── tabs.css
├── feedback/
│   ├── alerts.css
│   ├── badges.css
│   └── progress.css
└── components.css

7.7.2 主组件文件

/* components/components.css */
@import './base/buttons.css';
@import './base/forms.css';
@import './base/typography.css';
@import './layout/containers.css';
@import './layout/grid.css';
@import './layout/dividers.css';
@import './navigation/navbar.css';
@import './navigation/breadcrumb.css';
@import './navigation/tabs.css';
@import './feedback/alerts.css';
@import './feedback/badges.css';
@import './feedback/progress.css';

7.7.3 组件文档页面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>组件库文档</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="components/components.css">
</head>
<body class="bg-gray-50">
    <!-- 导航栏 -->
    <nav class="navbar">
        <div class="navbar-container">
            <div class="navbar-content">
                <div class="navbar-brand">
                    <div class="navbar-logo bg-blue-600 rounded"></div>
                    <span class="navbar-title">组件库</span>
                </div>
                <div class="navbar-nav">
                    <a href="#buttons" class="navbar-link">按钮</a>
                    <a href="#forms" class="navbar-link">表单</a>
                    <a href="#navigation" class="navbar-link">导航</a>
                    <a href="#feedback" class="navbar-link">反馈</a>
                </div>
            </div>
        </div>
    </nav>
    
    <!-- 主要内容 -->
    <main class="container-fluid py-8">
        <div class="max-w-6xl mx-auto">
            <!-- 按钮组件 -->
            <section id="buttons" class="mb-12">
                <h2 class="text-2xl font-bold text-gray-900 mb-6">按钮组件</h2>
                
                <div class="card mb-6">
                    <div class="card-header">
                        <h3 class="text-lg font-semibold">基础按钮</h3>
                    </div>
                    <div class="card-body">
                        <div class="flex flex-wrap gap-4 mb-4">
                            <button class="btn btn-primary">主要按钮</button>
                            <button class="btn btn-secondary">次要按钮</button>
                            <button class="btn btn-success">成功按钮</button>
                            <button class="btn btn-danger">危险按钮</button>
                        </div>
                        <pre class="bg-gray-100 p-4 rounded text-sm overflow-x-auto"><code>&lt;button class="btn btn-primary"&gt;主要按钮&lt;/button&gt;
&lt;button class="btn btn-secondary"&gt;次要按钮&lt;/button&gt;
&lt;button class="btn btn-success"&gt;成功按钮&lt;/button&gt;
&lt;button class="btn btn-danger"&gt;危险按钮&lt;/button&gt;</code></pre>
                    </div>
                </div>
                
                <div class="card mb-6">
                    <div class="card-header">
                        <h3 class="text-lg font-semibold">按钮尺寸</h3>
                    </div>
                    <div class="card-body">
                        <div class="flex flex-wrap items-center gap-4 mb-4">
                            <button class="btn btn-primary btn-sm">小按钮</button>
                            <button class="btn btn-primary">默认按钮</button>
                            <button class="btn btn-primary btn-lg">大按钮</button>
                            <button class="btn btn-primary btn-xl">超大按钮</button>
                        </div>
                        <pre class="bg-gray-100 p-4 rounded text-sm overflow-x-auto"><code>&lt;button class="btn btn-primary btn-sm"&gt;小按钮&lt;/button&gt;
&lt;button class="btn btn-primary"&gt;默认按钮&lt;/button&gt;
&lt;button class="btn btn-primary btn-lg"&gt;大按钮&lt;/button&gt;
&lt;button class="btn btn-primary btn-xl"&gt;超大按钮&lt;/button&gt;</code></pre>
                    </div>
                </div>
            </section>
            
            <!-- 表单组件 -->
            <section id="forms" class="mb-12">
                <h2 class="text-2xl font-bold text-gray-900 mb-6">表单组件</h2>
                
                <div class="card mb-6">
                    <div class="card-header">
                        <h3 class="text-lg font-semibold">输入框</h3>
                    </div>
                    <div class="card-body">
                        <div class="max-w-md">
                            <div class="form-group">
                                <label for="demo-input" class="form-label">标签</label>
                                <input type="text" id="demo-input" class="form-input" placeholder="请输入内容">
                                <p class="form-help">这是帮助文本</p>
                            </div>
                            
                            <div class="form-group">
                                <label for="demo-error" class="form-label">错误状态</label>
                                <input type="text" id="demo-error" class="form-input form-input-error" placeholder="错误输入">
                                <p class="form-error">这是错误信息</p>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
            
            <!-- 反馈组件 -->
            <section id="feedback" class="mb-12">
                <h2 class="text-2xl font-bold text-gray-900 mb-6">反馈组件</h2>
                
                <div class="card mb-6">
                    <div class="card-header">
                        <h3 class="text-lg font-semibold">警告框</h3>
                    </div>
                    <div class="card-body space-y-4">
                        <div class="alert alert-info">
                            <div class="alert-title">信息提示</div>
                            <div class="alert-description">这是一条信息提示消息。</div>
                        </div>
                        
                        <div class="alert alert-success">
                            <div class="alert-title">操作成功</div>
                            <div class="alert-description">您的操作已成功完成。</div>
                        </div>
                        
                        <div class="alert alert-warning">
                            <div class="alert-title">注意</div>
                            <div class="alert-description">请注意这个重要信息。</div>
                        </div>
                        
                        <div class="alert alert-error">
                            <div class="alert-title">错误</div>
                            <div class="alert-description">操作失败,请重试。</div>
                        </div>
                    </div>
                </div>
                
                <div class="card mb-6">
                    <div class="card-header">
                        <h3 class="text-lg font-semibold">徽章</h3>
                    </div>
                    <div class="card-body">
                        <div class="flex flex-wrap gap-2 mb-4">
                            <span class="badge badge-primary">主要</span>
                            <span class="badge badge-secondary">次要</span>
                            <span class="badge badge-success">成功</span>
                            <span class="badge badge-warning">警告</span>
                            <span class="badge badge-danger">危险</span>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </main>
</body>
</html>

7.8 组件化最佳实践

7.8.1 设计原则

  1. 一致性:保持设计和行为的一致性
  2. 可复用性:组件应该易于在不同场景中使用
  3. 可扩展性:支持通过修饰符类扩展功能
  4. 可访问性:确保组件符合无障碍访问标准
  5. 性能:避免不必要的样式重复

7.8.2 命名规范

  • BEM 方法论:Block__Element–Modifier
  • 语义化命名:使用有意义的类名
  • 前缀约定:为组件添加统一前缀
/* 好的命名示例 */
.btn { /* Block */ }
.btn__icon { /* Element */ }
.btn--large { /* Modifier */ }
.btn--primary { /* Modifier */ }

/* 避免的命名 */
.blue-button { /* 过于具体 */ }
.big { /* 过于通用 */ }
.btn1 { /* 无意义 */ }

7.8.3 文档化

  • 使用示例:提供清晰的使用示例
  • 参数说明:说明可用的修饰符和选项
  • 设计指南:说明何时使用该组件
  • 可访问性说明:提供无障碍访问指导

7.8.4 测试策略

  • 视觉回归测试:确保组件外观一致
  • 功能测试:验证组件行为正确
  • 可访问性测试:检查无障碍访问支持
  • 性能测试:监控组件性能影响

7.9 本章总结

在本章中,我们学习了组件化开发的核心概念和实践:

核心要点

  1. 组件化概念:理解组件化开发的优势和方法
  2. @apply 指令:使用 @apply 创建可复用的组件类
  3. 组件库构建:创建完整的 UI 组件库
  4. 最佳实践:遵循设计原则和命名规范
  5. 文档化:为组件提供完整的文档

最佳实践

  • 保持组件的一致性和可复用性
  • 使用语义化的命名规范
  • 提供完整的文档和示例
  • 注重可访问性和性能

下一步

在下一章中,我们将学习动画与过渡效果,了解如何为组件添加动态效果。

7.10 练习题

  1. 按钮组件练习:创建一个完整的按钮组件系统,包括不同状态、尺寸和样式
  2. 表单组件练习:构建一套表单组件,包括验证状态和帮助文本
  3. 卡片组件练习:设计一个灵活的卡片组件,支持不同的内容布局

练习提示

  • 使用 @apply 指令创建组件类
  • 考虑组件的可扩展性和复用性
  • 为组件编写使用文档
  • 测试组件在不同场景下的表现