CURD页面组件封装——详情弹窗组件

99 阅读3分钟

前言

对于面向企业的项目而言,前端开发中最常见的场景之一便是后台管理系统,而这类系统的核心页面多为基于表格表单的 CURD(增删改查)操作页面。随着同类页面开发量的增加,封装一套通用的 CURD 功能组件变得尤为必要——这不仅能显著提升开发效率,避免重复性工作,更能为后续的统一修改与维护提供便利。

一个标准的 CURD 页面通常包含以下核心功能模块:搜索条、操作工具条、数据表格、新增 / 编辑弹窗、详情弹窗等。

本方案将采用 “分而治之” 的策略:将每个功能模块封装为独立的基础组件,再通过组件组合的方式快速搭建完整的 CURD 页面。

在之前的文章中已经介绍了搜索条、数据表格、新增/编辑弹窗功能模块组件的封装,参见文章:

CURD页面组件封装——搜索组件

CURD页面组件封装——数据表格组件

CURD页面组件封装——新增/编辑弹窗组件

本篇文章将是该系列的最后一篇文章,用来介绍详情弹窗功能模块的封装实现细节。

详情弹窗

详情弹窗主要是对列表中数据条目更详细的展示,其相对于新增/编辑弹窗更简单,就是将表单控件转为显示字段的具体内容值。

对于需要特殊显示的内容,也可以通过配置插槽的方式实现。

image.png

实现

1.props参数

组件对外的参数有两个:data(详情数据对象)、columns(详情json配置项数组)

2.布局实现

详情的布局没有使用<el-descriptions>描述列表控件,而是选择<el-form>表单控件实现。这是因为前者无法很好的控制字段名称右对齐,需要css配合控制,而表格控件原生提供了字段名称的右对齐,更加方便。此外配合<el-col>栅格布局元素,能够更好的控制详情信息的分栏情况。

3.原生属性透传

v-bind="$attrs"外部属性绑定在<el-form>标签上,调用者可以直接使用 Element Plus 表单的所有原生属性,无需在封装组件中重复声明这些属性。

4.遍历生成详情信息

详情组件最核心的功能是遍历渲染。模板中通过v-for="item in columns"遍历配置数组,生成每个详情信息的容器<el-col>

<el-col>容器占据的栅格宽度可以通过每个配置项中的span参数指定。也可以通过组件属性透传的cols属性整体设置表单的列数进行布局的控制。

容器内部分为两种类型,一种是配置了slot参数,通过插槽外部自定义详情信息的内容;另一种是显示对应prop字段的详情信息。

<template>
  <el-dialog v-model="model" :title="$attrs.title || '详情'" :width="$attrs.width ?? 600" class="ts-detail-dialog">
    <el-form :model="data" label-width="auto" v-bind="$attrs">
      <el-row>
        <el-col v-for="item in columns" :key="item.prop" :span="item.span || 24 / ($attrs.cols || 1)">
          <slot v-if="item.slot" :name="item.slot" />
          <el-form-item v-else :label="item.label + ':'">
            <span>{{ data[item.prop] }}</span>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="model = false">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
defineProps({
  data: {
    type: Object,
    required: true,
    default: () => {}
  },
  columns: {
    type: Array,
    required: true,
    default: () => []
  }
});
defineOptions({
  inheritAttrs: false
});

const model = defineModel();
</script>

调用

以下为详情弹窗组件的完整调用示例。

<template>
  <!-- 详情弹窗 -->
  <ts-detail-dialog v-model="detailVisible" :data="detailData" :columns="detailColumns" :width="600" />
</template>
<script setup>
const detailVisible = ref(false);
const detailData = ref({});
const detailColumns = reactive([
  {
    prop: 'name',
    label: '姓名'
  },
  {
    prop: 'gender',
    label: '性别'
  },
  {
    prop: 'age',
    label: '年龄'
  },
  {
    prop: 'date',
    label: '出生日期'
  },
  {
    prop: 'address',
    label: '通讯地址',
    span: 24
  }
]);
function handleDetail(row) {
  detailData.value = row;
  detailVisible.value = true;
}
</script>

总结

详情弹窗组件与该系列中其他组件的实现方式一致,都是通过遍历json配置项列表来实现内容的渲染。

其实如果看过前面几篇文章的同学一定能够发现,整套CURD组件的实现原理都是一致的,都是通过遍历json配置项列表来实现同质内容的动态渲染,并且配合插槽参数实现个别自定义内容的插入,实现原理还是很简单的。