管理页面增删改查复用方法详解(通用 CRUD 组件化)

管理页面的增删改查复用,核心是把”列表加载、分页、搜索、新增、编辑、删除、表单校验”这套通用流程从业务代码里抽出来,封装成组合式函数与通用组件,业务页只用声明式配置就能组装出一个完整的管理模块。我们在企业级 AI 网关项目中落地了 useCrud 组合式函数 + 通用表格/表单/弹窗组件的方案,模型管理、应用管理、渠道配置三个模块共用同一套骨架,每个新模块从零开发到可用控制在半天以内,重复代码减少七成以上。下面给出可直接复用的封装思路。

一、先拆解哪些东西值得复用

1.1 增删改查的共性到底在哪

任何管理页都逃不开同一套流程:进页面拉列表、分页跳转、按条件搜索、打开弹窗新增、回填数据编辑、二次确认删除。业务之间的差异只在字段、接口和校验规则,流程骨架完全一致。把骨架抽出来,业务就只剩”配置”。

能力 通用实现 业务差异点
列表加载 useCrud 统一拉取与分页状态 列表接口路径与字段映射
搜索 搜索表单组件统一处理 搜索项声明配置
新增/编辑 弹窗 + 表单组件统一管理 表单字段与校验规则
删除 统一二次确认与回调 删除接口与提示字段
刷新/重置 统一暴露给页面 基本无差异

1.2 组件与 Hook 各管一层

组件管展示,Hook 管状态。表格、表单、弹窗这些 UI 用通用组件承接;数据状态、加载状态、请求方法用 Hook 承接。两者解耦后,同样的 Hook 可以配不同 UI 库,同一个组件也可以对接不同业务字段。

二、useCrud 组合式函数的设计

2.1 核心 API 契约

useCrud 接收一个配置对象,把接口封装、分页字段、主键字段、表单字段一次性声明清楚,返回列表数据与全套操作方法。

// composables/useCrud.ts
export function useCrud(options: CrudOptions) {
  const {
    api,               // { list, add, update, remove, detail }
    idField = 'id',
    rowsField = 'list',
    totalField = 'total',
    queryParams = {},
    formModel = {},
  } = options

  const list = ref<Record<string, any>[]>([])
  const total = ref(0)
  const loading = ref(false)
  const dialogVisible = ref(false)
  const editingId = ref<number | null>(null)

  async function load() {
    loading.value = true
    try {
      const res = await api.list({ ...queryParams, page, size })
      list.value = res[rowsField] ?? []
      total.value = res[totalField] ?? 0
    } finally {
      loading.value = false
    }
  }

  function openAdd() {
    editingId.value = null
    Object.keys(formModel).forEach((k) => (formModel[k] = ''))
    dialogVisible.value = true
  }

  function openEdit(row: Record<string, any>) {
    editingId.value = row[idField]
    Object.assign(formModel, row)
    dialogVisible.value = true
  }

  async function submit() {
    if (editingId.value) {
      await api.update(editingId.value, formModel)
    } else {
      await api.add(formModel)
    }
    dialogVisible.value = false
    load()
  }

  async function remove(row: Record<string, any>) {
    await api.remove(row[idField])
    load()
  }

  return { list, total, loading, dialogVisible, editingId, load, openAdd, openEdit, submit, remove }
}

2.2 通用表格组件的列定制

表格组件负责渲染列、分页和操作按钮,但列的展示逻辑各不相同。用”具名插槽自动接管”模式:业务页给某列提供了插槽就用插槽,没提供就走默认渲染,通用性与灵活性同时保住。

<!-- components/CrudTable.vue 关键片段 -->
<template>
  <el-table :data="rows" v-loading="loading">
    <el-table-column
      v-for="col in columns"
      :key="col.prop"
      :prop="col.prop"
      :label="col.label"
    >
      <template v-if="col.slot" #default="{ row }">
        <slot :name="col.slot" :row="row" />
      </template>
    </el-table-column>
    <el-table-column v-if="operations" label="操作" fixed="right">
      <template #default="{ row }">
        <slot name="actions" :row="row" />
      </template>
    </el-table-column>
  </el-table>
</template>

三、业务模块的组装方式

3.1 一个模块一页代码

模型管理页只需要声明列、接口和表单字段,其余交给通用层:

  1. 声明 apiService,指向后端标准化的 /model/page、/model、/model/{id} 接口;
  2. 声明 columns 列配置,特殊列(如状态标签、模型类型)指定 slot 名称;
  3. 声明 formFields,配置表单项类型、校验规则;
  4. 调用 useCrud 拿到数据与操作方法,模板里直接绑定。

3.2 表单的动态渲染

表单组件按 formFields 配置动态渲染表单项,字段类型支持输入框、下拉、开关、数字等,校验规则跟着字段走。新增一个模块不需要重写表单组件,只加字段配置。

3.3 事件回调与跨模块联动

业务模块在通用流程上还要挂自定义行为,比如新增模型后自动刷新渠道列表、删除应用后清掉关联缓存。useCrud 提供一个事件订阅位,业务页按模块名注册回调,通用层在增删改成功后统一派发,避免业务代码散落在各个组件里。

// 应用模块里订阅渠道模块的事件
crud.on('app:deleted', (id) => {
  channelStore.refresh(id)
})

权限按钮也走配置化:新增、编辑、删除三个操作绑定权限标识,组件渲染前统一校验,没有权限的按钮直接不渲染,权限规则收敛在一个配置表里维护。

3.4 接口层约定统一

后端按统一模式暴露接口:分页查询 GET /{module}/page、新增 POST /{module}、修改 PUT /{module}/{id}、删除 DELETE /{module}/{id}、详情 GET /{module}/{id}。接口统一之后,前端 apiService 用工厂函数批量生成,一个模块的请求封装不超过 20 行。

四、复用过程中的三个取舍

复杂业务的列不硬塞进通用组件。订单这类状态流转型模块,操作按钮语义与普通删除完全不同,直接用插槽接管,通用组件退化成纯布局容器,避免为了复用强行抽象。搜索条件的联动依赖建议在业务页里维护,不要在通用组件里做全局联动逻辑,否则通用层会越变越重。删除的二次确认文案按模块定制,用配置项传入而不是写死在组件里。

常见问题(FAQ)

Q1:通用 CRUD 组件会不会限制复杂业务?

不会。通用层只处理标准流程,复杂场景通过插槽接管,组件退化为布局容器。

Q2:新增和编辑怎么复用同一个弹窗?

同一弹窗组件,编辑时先回填数据再提交,提交前按是否有主键分流。

Q3:不同模块的分页字段不一致怎么办?

通过 useCrud 配置的 pageField、sizeField、totalField 字段名映射解决。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
参数猎人的头像参数猎人认证作者

相关推荐

返回顶部