设计可编辑表格组件

news2024/11/29 10:37:14

前言

什么是可编辑表格呢?简单来说就是在一个表格里面进行表单操作,执行增删改查。这在一些后台管理系统中是尤为常见的。
在这里插入图片描述
今天我们根据vue2 + element-ui来设计一个表单表格组件。(不涉及完整代码,想要使用完整功能可以看底部连接)

开始设计

1.表单组件

首先我们思考表格里面的表单元素应该如何实现。在用户使用的时候,我们希望用户传入一个指定的类型自动去匹配对应的表单组件。那我们就应该将所有类型做一个集成,并分别给他们一个类型名称。

当然,为了最大程度为他们保留在element-ui已经实现的属性与方法,formEle肯定接收的是一个对象,对象里面包含了他要展示的组件类型,一些原element-ui的属性方法,我们使用$attrs便可以直接将属性绑定到element-ui的表单组件上。

我们为这个表单元素组件取名为formEle,并最大程度为他们保留在element-ui已经实现的属性与方法。当然我们也可以修改一下一些常用属性的默认值,例如打开clearable清除属性,设置placeholder默认值。

下面是部分代码

<template>
  <el-input
    v-if="formType === 'input'"
    v-model="localValue"
    v-bind="$attrs"
    v-on="$listeners"
    :clearable="clearable"
    :placeholder="placeholder"
  >
    <template v-for="(value, name) in $slots" #[name]>
      <slot :name="name"> </slot>
    </template>
  </el-input>
  <el-input-number
    v-else-if="formType === 'inputNumber'"
    v-model="localValue"
    v-bind="$attrs"
    v-on="$listeners"
    :placeholder="placeholder"
  >
    <template v-for="(value, name) in $slots" #[name]>
      <slot :name="name"> </slot>
    </template>
  </el-input-number>
  <el-select
    v-else-if="formType === 'select'"
    v-model="localValue"
    v-bind="$attrs"
    v-on="$listeners"
    :clearable="clearable"
    :placeholder="placeholder"
  >
    <el-option
      v-for="item in options"
      v-bind="item"
      :key="item.value"
    ></el-option>
  </el-select>
  <el-date-picker
    v-else-if="formType === 'datePicker'"
    v-model="localValue"
    v-bind="$attrs"
    v-on="$listeners"
    :placeholder="placeholder"
    :endPlaceholder="endPlaceholder"
    :startPlaceholder="startPlaceholder"
  >
  </el-date-picker>
  <el-time-select
    v-else-if="formType === 'timeSelect'"
    v-model="localValue"
    v-bind="$attrs"
    v-on="$listeners"
    :placeholder="placeholder"
  >
  </el-time-select>
  <el-time-picker
    v-else-if="formType === 'timePicker'"
    v-model="localValue"
    v-bind="$attrs"
    v-on="$listeners"
    :placeholder="placeholder"
    :endPlaceholder="endPlaceholder"
    :startPlaceholder="startPlaceholder"
  >
  </el-time-picker>
  <el-switch
    v-else-if="formType === 'switch'"
    v-model="localValue"
    v-bind="$attrs"
    :placeholder="placeholder"
  >
  </el-switch>
  <el-cascader
    v-else-if="formType === 'cascader'"
    v-model="localValue"
    :options="options"
    ref="cascader"
    v-bind="$attrs"
    v-on="$listeners"
    :placeholder="placeholder"
  ></el-cascader>
</template>

<script>
export default {
  name: 'ClFormEle',
  props: {
    // 表单类型
    formType: {
      type: String,
      default: 'input'
    },
    modelValue: null,
    options: {
      type: Array,
      default: () => []
    }
  },
  model: {
    prop: 'modelValue',
    event: 'editModelValue'
  },
  computed: {
    localValue: {
      get() {
        return this.modelValue
      },
      set(val) {
        this.$emit('editModelValue', val)
      }
    },
    clearable() {
      return this.$attrs.clearable === false ? false : true
    },
    placeholder() {
      let text = '请选择'
      if (this.formType === 'input') {
        text = '请输入'
      }
      return this.$attrs.placeholder || text + (this.$attrs.label || '')
    },
    rangeSeparator() {
      return this.$attrs.rangeSeparator || '至'
    },
    startPlaceholder() {
      if (this.formType === 'datePicker') {
        return this.$attrs.startPlaceholder || '开始日期'
      } else {
        return this.$attrs.startPlaceholder || '开始时间'
      }
    },
    endPlaceholder() {
      if (this.formType === 'datePicker') {
        return this.$attrs.startPlaceholder || '结束日期'
      } else {
        return this.$attrs.startPlaceholder || '结束时间'
      }
    }
  },
  methods: {
    // 获取级联组件的回显值
    getCasLabelcader() {
      this.$nextTick(() => {
        return this.$refs.cascader?.inputValue
      })
    }
  }
}
</script>

<style lang="less" scoped>
.el-input {
  width: 100%;
  height: 30px;
}
.el-select {
  width: 100%;
}
.el-date-editor {
  width: 100%;
}
</style>

需要注意的是我们还需要将element-ui组件的插槽位置预留出来。

2.考虑表格组件

首先我们要想到我们可能会使用表单组件的校验等功能,那么在最外层就一定需要el-form来包裹表格组件。

其次是表单组件上model的绑定值的选择。可以预料的是我们最终绑定的数据一定是一个数组格式的。因为表格肯定不会只有一条数据。但是我们又无法在表单的model属性上绑定数组,所以我们可以将数组封装为数组对象的格式。

 <!-- modelValueCom 为表格数据 -->
<el-form ref="formRef" :model="{ formData: modelValueCom }">

接下来我们将对列的数据进行处理。列的数据肯定也是一个数组结构的,每列我们分为两个板块,一个是用在el-table-column上的属性值,一个则是内部表单内容的属性值。为了方便区分,我们将采用一些数据格式:

[
  {
    prop: 'name',
    label: '姓名',
    minWidth: '200px',
    formEle: {
      formType: 'input'
    }
  }
]

上面的formEle对象就行将来需要用在表单组件上的属性值,而其他属性则是直接作用在el-table-column上的。

<el-table-column
	v-for="columItem in columList"
	:key="columItem.prop"
	v-bind="getColumnAttr(columItem)"
>

getColumnAttr方法的作用就是剔除formEle属性

接着就是关于表单组件的使用了。既然我们需要表单的校验方法,我们就需要el-form-item组件来包裹表单组件,而组件上最重要的prop属性则可以直接在上面的列数据中获取,注意因为数据是数组,我们需要使用下标绑定到具体的哪条数据上,label属性我们则可以直接省略,因为我们已经有表头来展示了。

<el-form-item
   v-if="row.isEdit"
   :prop="'formData.' + $index + '.' + columItem.prop"
   :rules="columItem.formEle?.rules"
>

说到表头我们可能需要想到为他添加必填校验的表示符,我们在formEle里面加入showRequiredIcon属性判断是否需要展示必填校验。
在这里插入图片描述

<el-table-column
  v-for="columItem in columList"
  :key="columItem.prop"
  v-bind="getColumnAttr(columItem)"
>
  <template #default="{ row, $index }">
    <el-form-item
      v-if="row.isEdit"
      :prop="'formData.' + $index + '.' + columItem.prop"
      :rules="columItem.formEle?.rules"
    >
      <ClFormEle
        v-model="row[columItem.prop]"
        v-bind="columItem.formEle"
        v-on="eventMap[columItem.prop]"
        :label="columItem.label"
      ></ClFormEle>
    </el-form-item>
    <!-- getLabel方法用于回显,解析一些下拉,级联,时间等 -->
    <span v-else>{{
      getLabel(
        getFormType(columItem),
        columItem,
        row[columItem.prop],
        $index
      )
    }}</span>
  </template>
  <template #header>
    <span v-if="columItem.formEle?.showRequiredIcon" class="required_icon"
      >*</span
    >
    {{ columItem.label }}
  </template>
</el-table-column>

最后我们应该还需要有一列操作按钮对行数据进行修改,保存,删除等操作。修改,保存就是修改表格数据的isEdit属性,让在表单元素与span展示中切换。

<el-table-column v-bind="btnColCpd">
  <template #default="{ row, $index: index, column }">
    <slot name="endColumn" :data="{ row, index, column }">
      <el-button
        v-if="!row.isEdit"
        type="text"
        icon="el-icon-edit"
        @click.native.stop="rowEdit(index)"
        >修改</el-button
      >
      <el-button
        v-else
        type="text"
        icon="el-icon-check"
        @click.native.stop="saveRow(index)"
        >保存</el-button
      >
      <el-popconfirm
        v-if="isDelBtnTip"
        :title="delBtnTip"
        @confirm="delRow(index)"
      >
        <el-button
          type="text"
          icon="el-icon-delete"
          class="del_btn_text"
          slot="reference"
          >删除</el-button
        >
      </el-popconfirm>
      <el-button
        v-else
        type="text"
        icon="el-icon-delete"
        class="del_btn_text"
        slot="reference"
        @click.native.stop="delRow(index)"
        >删除</el-button
      >
    </slot>
  </template>
</el-table-column>

btnColCpd是一个关于最后一列属性配置对象,我们可以的使用element-ui里面el-table-column组件的属性来控制最后一列。

到这一个简单的表单组件结构就基本实现了。

当然,上面的设计还有很多的缺陷,比如表单组件的方法该如何绑定,各个表单组件插槽该如何抛出,表单的校验可不可以在离开行的时候触发,如果想要使用的组件formEle不包含怎么办等等,想要实现一个完整的表单表格组件这些都是必须要考虑的。我封装了一个较为完整的表单表格组件,大家可以在TableForm查看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1318263.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推荐EasyImages简单图床源码

开源好用EasyImages简单图床源码分享&#xff0c;虽然它是开源程序&#xff0c;但功能一点也不弱&#xff0c;不仅支持多文件上传、文字/图片水印、支持API和鉴黄、还能自定义代码&#xff0c;最重要的是它不强制使用数据库运行&#xff0c;这就给我们的部署和维护带来极大方便…

21--集合小案例

案例--图书管理系统 1.创建实体类Book package com.work.pojo; /** *Author: 憨憨浩浩 *CreateTime: 2023-12-16 17:27 *Description: Book实体类 */ public class Book {private int id; // 编号private String name; // 图书名称private String author;…

Stable-Diffusion|文生图 完蛋我被美女包围了人物Lora(四)

前面几篇&#xff1a; Stable-Diffusion|window10安装GPU版本的 Stable-Diffusion-WebUI遇到的一些问题&#xff08;一&#xff09; 【Stable-Diffusion|入门怎么下载与使用civitai网站的模型&#xff08;二&#xff09;】 Stable-Diffusion|文生图 拍立得纪实风格的Lora 图例&…

【JavaEE】多线程案例 - 定时器

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

漏洞复现-海康威视 NCG 联网网关 login.php 目录遍历漏漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

新增数据,某个字段的值总是保存不上问题解决

在系统中新增一条数据&#xff0c;某个字段的数据总是保存不上&#xff0c;但是没有报任何异常和错误&#xff0c;其他字段也都是正常的&#xff0c;通过抓包分析请求参数发现那个字段的值也没有传给后端&#xff0c;检查了前后端代码也没有排查到问题。百思不得其解&#xff0…

【5G PHY】5G小区类型、小区组和小区节点的概念介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

深入理解——快速排序

目录 &#x1f4a1;基本思想 &#x1f4a1;基本框架 &#x1f4a1;分割方法 ⭐Hoare版本 ⭐挖坑法 ⭐前后指针法 &#x1f4a1;优化方法 ⭐三数取中法 ⭐小区间内使用插入排序 &#x1f4a1;非递归实现快速排序 &#x1f4a1;性能分析 &#x1f4a1;基本思想 任取待排…

Java已死!

许多开发者仍然认为 Java 与当今时代息息相关&#xff0c;看完本文&#xff0c;你会发现 Java 的影响力已经大幅减弱。实际上&#xff0c;Java 是一种濒临灭绝的编程语言。尽管 Java 一直是世界上使用最广泛、最受欢迎的编程语言之一&#xff0c;但它很快就会面临消亡的危险。 …

【OpenHarmony 北向应用开发】ArkTS语言入门(构建应用页面)

ArkTS语言入门 在学习ArkTS语言之前&#xff0c;我们首先需要一个能够编译并运行该语言的工具 DevEco Studio。 了解ArkTS ArkTS是OpenHarmony优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继…

01--二分查找

一. 初识算法 1.1 什么是算法&#xff1f; 在数学和计算机科学领域&#xff0c;算法是一系列有限的严谨指令&#xff0c;通常用于解决一类特定问题或执行计算 不正式的说&#xff0c;算法就是任何定义优良的计算过程&#xff1a;接收一些值作为输入&#xff0c;在有限的时间…

【动态读取配置文件】ParameterTool读取带环境的配置信息

不同环境Flink配置信息是不同的&#xff0c;为了区分不同环境的配置文件&#xff0c;使用ParameterTool工具读取带有环境的配置文件信息 区分环境的配置文件 三个配置文件&#xff1a; flink.properties&#xff1a;决定那个配置文件生效 flink-dev.properties&#xff1a;测…

【计算机网络】—— 详解码元,传输速率的计算|网络奇缘系列|计算机网络

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 码元 速率和波特 思考1 思考2 思考3 带宽&#xff08;Bandwidth&#xff09; &#x1f4dd;总结 码元…

MapReduce序列化实例代码

1 &#xff09;需求&#xff1a;统计每个学号该月的超市消费、食堂消费、总消费 2 &#xff09;输入数据格式 序号 学号 超市消费 食堂消费 18 202200153105 8.78 12 3 &#xff09;期望输出格式 key &#xff08;学号&#xff09; value &#xff08; bean 对象&#xf…

用Rust刷LeetCode之58 最后一个单词的长度

58. 最后一个单词的长度[1] 难度: 简单 原描述: 思路 使用标准库: package mainimport ( "fmt" "strings")func lengthOfLastWord(s string) int { s strings.TrimSpace(s) // 删除 首尾 的空格 arr : strings.Split(s, " ") // 字符串转为切片…

FL Studio 21.1.0.3713中文版最新安装激活图文教程及系统配置要求

FL Studio 21.1.0.3713中文版是一款功能强大的编曲软件&#xff0c;它也能够剪辑、混音、录音&#xff0c;它的矢量界面&#xff0c;能更好用在4K、5K甚至8K显示器上。完全重新设计混音器、动态缩放、具有 6 种布局风格、外加 3个用户自定义面板管理音轨、多推子选择和调整、混…

Python 反编译Il2Cpp APK

引入 https://github.com/Perfare/Il2CppDumper/ 实现 开源的Ii2Cpp Dumper可以帮助我们将So和globalmetadata.dat文件反编译出 Assembly-CSharp.dll 本博客教程可以帮助我们直接拖入APK反编译出来 调用方式 两种 第一种 拖入后回车运行 第二种 放入运行的根目录下 源码 i…

Pandas-DataFtame的索引与切片(第3讲)

Pandas-DataFtame的索引与切片(第3讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

数据解密战:.mallox勒索病毒攻击下的数据保护

引言&#xff1a; 近期&#xff0c;网络安全领域再度掀起一场不安的浪潮&#xff0c;.Mallox勒索病毒作为最新一位悍匪登场&#xff0c;以其毒辣的加密技术&#xff0c;将用户的数据转瞬间变成了无解之谜。这股数字黑暗力量的出现引起了广泛关注&#xff0c;让用户和企业重新审…

事件监听的艺术:掌握`addEventListener`的魅力

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…