zdppy+vue3+antd 实现表格单元格编辑功能
初步实现
<template><a-button class="editable-add-btn" style="margin-bottom: 8px" @click="handleAdd">Add</a-button><a-table bordered :data-source="dataSource" :columns="columns"><template #bodyCell="{ column, text, record }"><!--make the name column editable--><template v-if="column.dataIndex === 'name'"><div class="editable-cell"><div v-if="editableData[record.key]" class="editable-cell-input-wrapper"><a-input v-model:value="editableData[record.key].name" @pressEnter="save(record.key)"/><check-outlined class="editable-cell-icon-check" @click="save(record.key)"/></div><div v-else class="editable-cell-text-wrapper">{{ text || ' ' }}<edit-outlined class="editable-cell-icon" @click="edit(record.key)"/></div></div></template><!--Action column--><template v-else-if="column.dataIndex === 'operation'"><a-popconfirmv-if="dataSource.length"title="Sure to delete?"@confirm="onDelete(record.key)"><a>Delete</a></a-popconfirm></template></template></a-table>
</template>
<script setup>
import {computed, reactive, ref} from 'vue';
import {CheckOutlined, EditOutlined} from "@ant-design/icons-vue";
import {cloneDeep} from 'lodash-es';const columns = [{title: 'name',dataIndex: 'name',width: '30%',},{title: 'age',dataIndex: 'age',},{title: 'address',dataIndex: 'address',},{title: 'operation',dataIndex: 'operation',},
];
const dataSource = ref([{key: '0',name: 'Edward King 0',age: 32,address: 'London, Park Lane no. 0',},{key: '1',name: 'Edward King 1',age: 32,address: 'London, Park Lane no. 1',},
]);
const count = computed(() => dataSource.value.length + 1);
const editableData = reactive({});// make the row editable
const edit = key => {editableData[key] = cloneDeep(dataSource.value.filter(item => key === item.key)[0]);
};// save the edit result
const save = key => {Object.assign(dataSource.value.filter(item => key === item.key)[0], editableData[key]);delete editableData[key];
};// delete the row
const onDelete = key => {dataSource.value = dataSource.value.filter(item => item.key !== key);
};// add a row to data source
const handleAdd = () => {const newData = {key: `${count.value}`,name: `Edward King ${count.value}`,age: 32,address: `London, Park Lane no. ${count.value}`,};dataSource.value.push(newData);
};
</script>
<style lang="less" scoped>
.editable-cell {position: relative;.editable-cell-input-wrapper,.editable-cell-text-wrapper {padding-right: 24px;}.editable-cell-text-wrapper {padding: 5px 24px 5px 5px;}.editable-cell-icon,.editable-cell-icon-check {position: absolute;right: 0;width: 20px;cursor: pointer;}.editable-cell-icon {margin-top: 4px;display: none;}.editable-cell-icon-check {line-height: 28px;}.editable-cell-icon:hover,.editable-cell-icon-check:hover {color: #108ee9;}.editable-add-btn {margin-bottom: 8px;}
}.editable-cell:hover .editable-cell-icon {display: inline-block;
}
</style>
渲染后端接口数据
<script setup>
import {computed, onMounted, reactive, ref} from 'vue';
import {CheckOutlined, EditOutlined} from "@ant-design/icons-vue";
import {cloneDeep} from 'lodash-es';
import axios from "axios";const columns = [{name: '姓名',dataIndex: 'name',key: 'name',},{name: '性别',dataIndex: 'gender',key: 'gender',},{title: '年龄',dataIndex: 'age',key: 'age',},{title: '电话',dataIndex: 'phone',key: 'phone',},{title: '邮箱',key: 'email',dataIndex: 'email',},{title: '薪资',key: 'salary',dataIndex: 'salary',},{title: '操作',key: 'action',},
];const dataSource = ref([]);onMounted(() => {axios.get("http://127.0.0.1:8889/zdppy_amuserdetail").then((response) => {console.log("response.data", response.data);dataSource.value = response.data.data.results;})
})const count = computed(() => dataSource.value.length + 1);
const editableData = reactive({});// make the row editable
const edit = id => {console.log("edit", editableData, id)editableData[id] = cloneDeep(dataSource.value.filter(item => id === item.id)[0]);
};// save the edit result
const save = id => {Object.assign(dataSource.value.filter(item => id === item.id)[0], editableData[id]);delete editableData[id];
};// add a row to data source
const handleAdd = () => {const newData = {key: `${count.value}`,name: `Edward King ${count.value}`,age: 32,address: `London, Park Lane no. ${count.value}`,};dataSource.value.push(newData);
};
</script><template><a-button class="editable-add-btn" style="margin-bottom: 8px" @click="handleAdd">Add</a-button><a-tablebordered:data-source="dataSource":columns="columns":row-key="record => record.id"><template #headerCell="{ column }"><template v-if="column.key === 'name'"><span>{{ column.name }}</span></template><template v-else-if="column.key === 'gender'"><span>{{ column.name }}</span></template></template><template #bodyCell="{ column, text, record }"><!--make the name column editable--><template v-if="column.dataIndex === 'name'"><div class="editable-cell"><div v-if="editableData[record.id]" class="editable-cell-input-wrapper"><a-input v-model:value="editableData[record.id].name" @pressEnter="save(record.id)"/><check-outlined class="editable-cell-icon-check" @click="save(record.id)"/></div><div v-else class="editable-cell-text-wrapper">{{ text || ' ' }}<edit-outlined class="editable-cell-icon" @click="edit(record.id)"/></div></div></template><!--Action column--><template v-else-if="column.key === 'action'"><a-space wrap><a-button size="small" type="primary" block>编辑</a-button><a-button size="small" block>详情</a-button><a-button size="small" danger block>删除</a-button></a-space></template></template></a-table>
</template>
<style lang="less" scoped>
.editable-cell {position: relative;.editable-cell-input-wrapper,.editable-cell-text-wrapper {padding-right: 24px;}.editable-cell-text-wrapper {padding: 5px 24px 5px 5px;}.editable-cell-icon,.editable-cell-icon-check {position: absolute;right: 0;width: 20px;cursor: pointer;}.editable-cell-icon {margin-top: 4px;display: none;}.editable-cell-icon-check {line-height: 28px;}.editable-cell-icon:hover,.editable-cell-icon-check:hover {color: #108ee9;}.editable-add-btn {margin-bottom: 8px;}
}.editable-cell:hover .editable-cell-icon {display: inline-block;
}
</style>
将修改的数据保存到数据库
<script setup>
import {computed, onMounted, reactive, ref} from 'vue';
import {CheckOutlined, EditOutlined} from "@ant-design/icons-vue";
import {cloneDeep} from 'lodash-es';
import axios from "axios";const columns = [{name: '姓名',dataIndex: 'name',key: 'name',},{name: '性别',dataIndex: 'gender',key: 'gender',},{title: '年龄',dataIndex: 'age',key: 'age',},{title: '电话',dataIndex: 'phone',key: 'phone',},{title: '邮箱',key: 'email',dataIndex: 'email',},{title: '薪资',key: 'salary',dataIndex: 'salary',},{title: '操作',key: 'action',},
];const dataSource = ref([]);onMounted(() => {axios.get("http://127.0.0.1:8889/zdppy_amuserdetail").then((response) => {console.log("response.data", response.data);dataSource.value = response.data.data.results;})
})const count = computed(() => dataSource.value.length + 1);
const editableData = reactive({});// make the row editable
const edit = id => {console.log("edit", editableData, id)editableData[id] = cloneDeep(dataSource.value.filter(item => id === item.id)[0]);
};// save the edit result
const save = id => {const data = editableData[id]console.log("updated data", data)// backend updateaxios({method: "put",url: "http://127.0.0.1:8889/zdppy_amuserdetail/" + id,contentType: "application/json",data,}).then(resp => {console.log("update", resp.data);})// frontedn updateObject.assign(dataSource.value.filter(item => id === item.id)[0], editableData[id]);delete editableData[id];
};// add a row to data source
const handleAdd = () => {const newData = {key: `${count.value}`,name: `Edward King ${count.value}`,age: 32,address: `London, Park Lane no. ${count.value}`,};dataSource.value.push(newData);
};
</script><template><a-button class="editable-add-btn" style="margin-bottom: 8px" @click="handleAdd">Add</a-button><a-tablebordered:data-source="dataSource":columns="columns":row-key="record => record.id"><template #headerCell="{ column }"><template v-if="column.key === 'name'"><span>{{ column.name }}</span></template><template v-else-if="column.key === 'gender'"><span>{{ column.name }}</span></template></template><template #bodyCell="{ column, text, record }"><!--make the name column editable--><template v-if="column.dataIndex === 'name'"><div class="editable-cell"><div v-if="editableData[record.id]" class="editable-cell-input-wrapper"><a-input v-model:value="editableData[record.id].name" @pressEnter="save(record.id)"/><check-outlined class="editable-cell-icon-check" @click="save(record.id)"/></div><div v-else class="editable-cell-text-wrapper">{{ text || ' ' }}<edit-outlined class="editable-cell-icon" @click="edit(record.id)"/></div></div></template><!--Action column--><template v-else-if="column.key === 'action'"><a-space wrap><a-button size="small" type="primary" block>编辑</a-button><a-button size="small" block>详情</a-button><a-button size="small" danger block>删除</a-button></a-space></template></template></a-table>
</template>
<style lang="less" scoped>
.editable-cell {position: relative;.editable-cell-input-wrapper,.editable-cell-text-wrapper {padding-right: 24px;}.editable-cell-text-wrapper {padding: 5px 24px 5px 5px;}.editable-cell-icon,.editable-cell-icon-check {position: absolute;right: 0;width: 20px;cursor: pointer;}.editable-cell-icon {margin-top: 4px;display: none;}.editable-cell-icon-check {line-height: 28px;}.editable-cell-icon:hover,.editable-cell-icon-check:hover {color: #108ee9;}.editable-add-btn {margin-bottom: 8px;}
}.editable-cell:hover .editable-cell-icon {display: inline-block;
}
</style>
相关文章:
zdppy+vue3+antd 实现表格单元格编辑功能
初步实现 <template><a-button class"editable-add-btn" style"margin-bottom: 8px" click"handleAdd">Add</a-button><a-table bordered :data-source"dataSource" :columns"columns"><templa…...
elasticsearch索引怎么设计
Primary Shard(主分片) Primary Shard(主分片)是索引数据存储的基本单位,承担着数据写入和查询的职责。以下是关于Primary Shard的一些关键点: 1. 数据分布:每个索引在创建时会被分成多个主分…...
React 中 useState 和 useReducer 的联系和区别
文章目录 使用场景使用 useState使用 useReducer 联系区别用法状态更新逻辑适用场景可读性和可维护性 使用场景 使用 useState 状态逻辑简单。只涉及少量的状态更新。需要快速和简单的状态管理。 使用 useReducer 状态逻辑复杂。涉及多个子状态或多种状态更新逻辑。需要更好…...
Linux 定时任务详解:全面掌握 cron 和 at 命令
Linux 定时任务详解:全面掌握 cron 和 at 命令 Linux 系统中定时任务的管理对于运维和开发人员来说都是至关重要的。通过定时任务,可以在特定时间自动执行脚本或命令,提高系统自动化程度。本文将详细介绍 Linux 中常用的定时任务管理工具 cr…...
力扣考研经典题 反转链表
核心思想 头插法: 不断的将cur指针所指向的节点放到头节点之前,然后头节点指向cur节点,因为最后返回的是head.next 。 解题思路 1.如果头节点是空的,或者是只有一个节点,只需要返回head节点即可。 if (head null …...
opencv 设置超时时间
经常爬视频数据,然后用opencv做成图片 因此设置超时时间很重要 cap.set(cv2.CAP_PROP_FPS, timeout_ms) for idx, row in data.iterrows(): if idx < 400: continue try: # 打开视频文件 timeout_ms 5000 cap cv2.VideoCapture(row[PLAY_URL]) cap.set(cv2.C…...
2024年7月6日随笔
期末考试全部结束了,这个月是真累啊,一堆事,好在都熬过来了,上次参加的那个码题杯自己居然进国赛了,我看了一下职业赛道和本科赛道的题,本科赛道的感觉要难上不少,比赛时间是一周后,…...
Ubuntu 打开或关闭界面
设置开机默认关闭图形界面 1. 设置系统默认启动到多用户目标(命令行界面): o 使用以下命令将系统默认启动目标设置为多用户目标(这会关闭图形界面): sudo systemctl set-default multi-use…...
使用京东云主机搭建幻兽帕鲁游戏联机服务器全流程,0基础教程
使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程,非常简单,京东云推出幻兽帕鲁镜像系统,镜像直接选择幻兽帕鲁镜像即可一键自动部署,不需要手动操作,真正的新手0基础部署幻兽帕鲁,阿腾云整理基于京…...
Python和MATLAB微机电健康推导算法和系统模拟优化设计
🎯要点 🎯惯性测量身体活动特征推导健康状态算法 | 🎯卷积网络算法学习惯性测量数据估计六自由度姿态 | 🎯全球导航卫星系统模拟,及惯性测量动态测斜仪算法、动态倾斜算法、融合算法 | 🎯微机电系统加速度…...
IT之家最新科技热点 | 小米 AI 研究院开创多模态通用模型
人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…...
黑色矩形块检测数据集VOC+YOLO格式2000张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2000 标注数量(xml文件个数):2000 标注数量(txt文件个数):2000 标注…...
Linux内存管理--系列文章柒——硬件架构
一、引子 之前文章讲解的是系统的虚拟内存,本章讲述这些硬件的架构和系统怎样统一管理这些硬件的。 二、物理内存模型 物理内存模型描述了计算机系统中的物理内存如何由操作系统组织和管理。它定义了物理内存如何划分为单元,如何寻址这些单元以及如何…...
QQ音乐Android一面凉经
最近面试了不少公司, 近期告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是QQ音乐Android一面凉经。 面试岗位: QQ音乐Android开发工程师面试时长: 50min(提问40min 反问10min)代码考核: 无 面试问题(40min) 自我介绍 工作经历, 重点…...
浅谈进程隐藏技术
前言 在之前几篇文章已经学习了解了几种钩取的方法 浅谈调试模式钩取浅谈热补丁浅谈内联钩取原理与实现导入地址表钩取技术 这篇文章就利用钩取方式完成进程隐藏的效果。 进程遍历方法 在实现进程隐藏时,首先需要明确遍历进程的方法。 CreateToolhelp32Snapsh…...
【C++】Google Test(gtest)单元测试
文章目录 Google Test(gtest)单元测试使用示例更多用法测试夹具 Google Test(gtest)单元测试 单元测试是一种软件测试方法,它旨在将应用程序的各个部分(通常是方法或函数)分离出来并独立测试&a…...
水箱高低水位浮球液位开关
水箱高低水位浮球液位开关概述 水箱高低水位浮球液位开关是一种用于监测和控制水箱中液位的自动化设备,它能够在水箱液位达到预设的高低限制时,输出开关信号,以控制水泵或电磁阀的开闭,从而维持水箱液位在一个安全的范围内。这类设…...
Autoware内容学习与初步探索(一)
0. 简介 之前作者主要是基于ROS2,CyberRT还有AutoSar等中间件完成搭建的。有一说一,这种从头开发当然有从头开发的好处,但是如果说绝大多数的公司还是基于现成的Apollo以及Autoware来完成的。这些现成的框架中也有很多非常好的方法。目前作者…...
【手写数据库内核组件】01 解析树的结构,不同类型的数据结构组多层的链表树,抽象类型统一引用格式
不同类型的链表 专栏内容: postgresql使用入门基础手写数据库toadb并发编程 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 文章目录 不同类型…...
Pandas 进阶 —— 数据转换、聚合与可视化
引言 在数据分析的旅程中,Pandas 库提供了从数据转换到聚合再到可视化的全面解决方案。上篇我们掌握了数据的导入和清洗,本篇我们将探索如何通过 Pandas 对数据进行更高级的处理,包括数据转换、聚合分析以及可视化展示。 数据转换 数据转换…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
CppCon 2015 学习:REFLECTION TECHNIQUES IN C++
关于 Reflection(反射) 这个概念,总结一下: Reflection(反射)是什么? 反射是对类型的自我检查能力(Introspection) 可以查看类的成员变量、成员函数等信息。反射允许枚…...
Java多线程实现之Runnable接口深度解析
Java多线程实现之Runnable接口深度解析 一、Runnable接口概述1.1 接口定义1.2 与Thread类的关系1.3 使用Runnable接口的优势 二、Runnable接口的基本实现方式2.1 传统方式实现Runnable接口2.2 使用匿名内部类实现Runnable接口2.3 使用Lambda表达式实现Runnable接口 三、Runnabl…...
Easy Excel
Easy Excel 一、依赖引入二、基本使用1. 定义实体类(导入/导出共用)2. 写 Excel3. 读 Excel 三、常用注解说明(完整列表)四、进阶:自定义转换器(Converter) 其它自定义转换器没生效 Easy Excel在…...
AT模式下的全局锁冲突如何解决?
一、全局锁冲突解决方案 1. 业务层重试机制(推荐方案) Service public class OrderService {GlobalTransactionalRetryable(maxAttempts 3, backoff Backoff(delay 100))public void createOrder(OrderDTO order) {// 库存扣减(自动加全…...
