Skip to content

2.1 组件模板

在企业级后台系统中,组件是构建页面的基础单元。与 C 端不同,B 端更注重功能完整性、交互一致性与复用效率。因此,我们需要围绕业务场景封装出可复用、易维护、结构清晰的组件模板。

本文档主要围绕组件设计原则、分类建议和使用方式展开,适用于 Vue 或 React 技术栈下的开发场景。

一、组件设计原则

职责单一

每个组件只负责一个功能或 UI 元素,不依赖外部状态;
示例:按钮组件只处理点击行为,不包含 API 调用逻辑;

高内聚低耦合

组件内部逻辑完整,对外暴露必要的 props 和 events;
避免直接操作 DOM 或引入全局变量;

可扩展性强

支持自定义属性和插槽机制,适应不同业务需求;
如支持 size、theme、custom-class 等参数;

语义清晰

组件命名具有明确业务含义,如 DataGrid、SearchBar、ModalForm;
不推荐模糊命名,如 ComponentA、BaseComp;

样式隔离

使用 scoped 样式或 CSS Modules,避免样式污染;
所有组件默认提供 class 属性用于扩展;

二、组件分类与使用建议

1. 基础组件(Base Components)

最底层的 UI 构建块,不包含业务逻辑;
示例:Button、Input、Select、Table、Modal;
推荐封装为独立组件库,供多个项目复用;
所有基础组件需提供完整的文档与示例;

2. 业务组件(Business Components)

封装特定业务逻辑的组件;
示例:UserTable、OrderCard、RoleSelector;
可基于基础组件组合而成,适配具体业务场景;
提供统一的数据格式要求,便于后期维护;

3. 容器组件(Container Components)

负责数据获取与状态管理;
示例:UserProfileContainer、DashboardContainer;
通常包裹多个展示组件并处理数据流;
不直接渲染复杂 UI,侧重逻辑组织;

4. 展示组件(Presentational Components)

只关注 UI 渲染,接收 props 并输出视图;
示例:UserInfoDisplay、OrderItem;
无副作用,易于测试和复用;
推荐使用函数组件 + hooks 实现;

三、组件结构规范(以 Vue 单文件组件为例)

vue
<template>
  <button class="btn" :class="typeClass" @click="handleClick">
    <span v-if="loading" class="spinner"></span>
    <slot>{{ label }}</slot>
  </button>
</template>

<script>
export default {
  name: 'BaseButton',
  props: {
    label: {
      type: String,
      required: true
    },
    type: {
      type: String,
      default: 'default', // default | primary | danger
      validator: value => ['default', 'primary', 'danger'].includes(value)
    },
    loading: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    typeClass() {
      return `btn-${this.type}`;
    }
  },
  methods: {
    handleClick() {
      if (!this.loading) {
        this.$emit('click');
      }
    }
  }
};
</script>

<style scoped>
.btn {
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
}
.btn-default {
  background-color: #f0f0f0;
  color: #333;
}
.btn-primary {
  background-color: #1890ff;
  color: #fff;
}
.btn-danger {
  background-color: #ff4d4f;
  color: #fff;
}
.spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid #fff;
  border-top: 2px solid transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}
@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
</style>

四、常用业务组件示例

组件名功能说明
DataGrid支持分页、排序、列配置的表格组件
ModalForm弹窗形式的表单组件,用于新增/编辑
SearchBar搜索区域组件,支持多条件筛选
StepWizard多步骤引导组件,适合创建向导流程
PermissionDirective自定义权限指令,控制元素是否显示
UserCard用户信息卡片,展示头像、姓名、角色等信息

五、组件文档编写建议

每个组件应配有说明文档,内容包括:

  • 功能描述
  • props 表格(类型、默认值、是否必填)
  • events 列表
  • 插槽说明
  • 使用示例代码
  • 设计截图(如有)

示例组件文档:BaseButton 按钮组件

Props

参数名类型默认值必填说明
labelstring-按钮显示文本
typestringdefault按钮类型
loadingbooleanfalse是否显示加载状态

Events

事件名参数说明
click-点击按钮时触发

插槽

插槽名说明
default按钮主体内容

示例代码

vue
<BaseButton label="提交" type="primary" @click="submitForm" />

六、组件测试建议

  • 使用 Jest/Vitest 编写组件单元测试;
  • 测试内容包括:
    • props 正确渲染
    • events 触发正确
    • 插槽内容显示正常
  • 对于业务组件,建议配合 Mock 数据进行集成测试;
  • 所有组件都应附带测试用例,确保稳定性;

七、组件库实践建议

  • 将常用组件抽取为独立 npm 包或 monorepo 子模块;
  • 遵循语义化版本号,每次更新记录变更日志;
  • 支持通过 SCSS 变量或 CSS Variables 自定义主题;
  • 结合 Babel 插件实现自动按需引入;
  • 提供完整的 TypeScript 类型定义文件(.d.ts);