vue3 + Element Plus动态生成表格,并实现内容可编辑

您所在的位置:网站首页 怎样制作在线编辑表格 vue3 + Element Plus动态生成表格,并实现内容可编辑

vue3 + Element Plus动态生成表格,并实现内容可编辑

2024-06-08 14:31| 来源: 网络整理| 查看: 265

目录 前言一、思路一:单元格数据转对象1.1 首先最基本的,根据数据生成固定表项的表格1.2 动态生成表项1.3 单元格可编辑1.4 插入、删除一行或一列数据1.5 完整代码1.6 vue2的坑:“列”变化出现的监听问题 二、思路二:精准定位编辑数据完整代码 三、组件复用

前言

第一个思路得自于网友的讨论,将单元格数据转对象,通过添加控制属性实现编辑状态与显示状态的切换。尽管思路简单,但实现的过程有些看着头大,不够简洁优美。采用这种方法的话,建议浏览了解后自行理清思路实现。

前段时间看到同事在类似问题上找了一个插件,简单得通过一个输入框就实现了对所有数据的编辑。仔细想想,只要能实现数据的“定位”,这种思路在实现过程上显得更加友好。

注意,示例基于 vue3 & [email protected],高版本的 element-plus 中图标引入方式不同

代码仓库:editable-table Github Page 在线演示 - 方案一 在线演示 - 方案二

注意:示例项目及文章写于2020年,基于 vue2 & element-ui,后来更新至 vue3 & element-plus,老版本在分支vue2上。由于只是demo,介绍解决方案方便理解与讨论,上生产环境的话肯定存在一些bug,有些必要的会修复,不必要的还请大家自行本地调试😉

一、思路一:单元格数据转对象

将单元格数据转换成对象,添加show属性,控制/切换显示与编辑模式

最终效果如下,可自由编辑表头、数据单元格,增删行列,并保持数据绑定

在这里插入图片描述 在这里插入图片描述

1.1 首先最基本的,根据数据生成固定表项的表格

从官网摘个Demo过来:

tableData: [ {date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄'}, {date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄'} ]

在这里插入图片描述

1.2 动态生成表项

常用的写法:

columnList: [ { prop: "name", label: '姓名' }, { prop: "age", label: '年龄' }, { prop: "city", label: '城市' }, { prop: "tel", label: '电话' } ], testDatas: [ {No: 1, name: '张三', age: 24, city: '广州', tel: '13312345678'}, {No: 2, name: '李四', age: 25, city: '九江', tel: '18899998888'}, {No: 3, name: '王五', age: 26, city: '六盘水', tel: '13600001111'}, {No: 4, name: '赵二', age: 27, city: '菏泽', tel: '13145209420'}, ]

在这里插入图片描述

1.3 单元格可编辑

网上早有网友讨论过这个功能,这里采用的是将单元格数据转换成对象,添加属性show来控制其在文字与输入框间切换。听起来就不想下手,又要转换数据格式了。。

// 表项(头),以键(prop)值(label)存储表头,值可改变,键不变用以绑定数据 columnList: [ { prop: "name", label: 'name', show: true }, { prop: "age", label: 'age', show: true }, { prop: "city", label: 'city', show: true }, { prop: "tel", label: 'tel', show: true } ], // 数据 testDatas: [{ name: { content: '张三', show: true }, age: { content: 24, show: true }, city: { content: '广州', show: true }, tel: { content: '13312345678', show: true } },{ name: { content: '李四', show: true }, age: { content: 25, show: true }, city: { content: '九江', show: true }, tel: { content: '18899998888', show: true } }], {{column.label}} {{row[column.prop].content}} // ... methods: { /** * 表头/单元格编辑处理:切换编辑输入框/文本输入框,自动聚焦 * * @param {Object} cell - The cell object to edit. * @param {HTMLElement} pEl - The parent element of the cell. */ handleEdit(cell, pEl) { const editIputEl = Array.from(pEl.nextSibling.childNodes).find(n => ['INPUT','TEXTAREA'].includes(n.tagName)) cell.show = false editIputEl && this.$nextTick(() => { editIputEl.focus() }) }, }

在这里插入图片描述

1.4 插入、删除一行或一列数据

做到第三点,这一步就没什么难度了,无非就是更改数组 想要实现对每一行每一列的操作,要用到Element表格插件提供的一些属性方法

行的 className 的回调方法:row-class-name给行加下标(非常关键,“定位”单元格的基础)列的index属性(非常关键,“定位”单元格的基础)编辑框的控制与数据绑定 @header-contextmenu:表头右键事件@row-contextmenu:数据行右键事件 功能 // 添加表格行下标 tableRowClassName({row, rowIndex}) { row.row_index = rowIndex }, rightClick(row, column, $event) { // 阻止浏览器自带的右键菜单弹出 $event.preventDefault() if(column.index == null) return // 表格容器的位置 const { x: tbX, y: tbY } = this.$refs.tbContainerRef.getBoundingClientRect() // 当前鼠标位置 const { x: pX, y: pY } = $event // 定位菜单 const ele = document.getElementById('contextmenu') ele.style.top = pY - tbY - 6 + 'px' ele.style.left = pX - tbX - 6 + 'px' this.showMenu = true },

在这里插入图片描述

1.5 完整代码

Git链接 在线演示

1.6 vue2的坑:“列”变化出现的监听问题

vue3可跳过

vue2开发中,新增列的时候,要为所有行添加新的对象,通过一般的添加对象属性是无法被vue监听到的。具体参考这篇文章:关于vue无法侦听数组及对象属性的变化的解决方案

addColumn(idx) { // 新增列 var obj = {col: 'col_' + this.count_col++, txt: '', show: true} // 新增列对象 this.testDatas.map(p => { _this.$set(p, obj.col, {content: '', show: true}) // p[obj.col] = {content: '', show: true} }) } 二、思路二:精准定位编辑数据

双击修改数据: 在这里插入图片描述

右键编辑行列: 在这里插入图片描述

这个思路的实现代码很简洁清晰,就不像上一个那么详细写了

相关要点:

el-table的单元格双击事件cell-dblclick行的 className 的回调方法:row-class-name给行加下标(非常关键,“定位”单元格的基础)列的index属性(非常关键,“定位”单元格的基础)编辑框的控制与数据绑定 @header-contextmenu:表头右键事件@row-contextmenu:数据行右键事件@cell-dblclick:单元格双击事件 功能 表项名称 cellDblclick():单元格双击事件 - 更改单元格数值

-> 双击显示输入框(#editInput) -> 找到双击的单元格数据 -> 输入框赋初值 -> 失焦或enter后将输入框的值赋给选中的单元格数据

rightClick():单元格/表头右击事件 - 打开菜单

-> 右击显示菜单(#contextmenu) -> 根据表头、表格显示对应菜单 -> 点击调用对应的功能方法

tableRowClassName():添加表格行下标 完整代码

Git链接 在线演示

三、组件复用

如果vue项目中需大量运用到此功能,可以通过生成组件来复用。需要注意父子组件间数据的双向绑定。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3