vue3 + element Plus实现表格根据关键字合并行,并实现行的增删改操作

根据关键字合并表格

    • 1.实现初始化表格
    • 2.实现添加班级与学生的功能
    • 3.添加的弹窗
    • 4.删除班级
    • 5.删除学生

首先看最终实现的效果

请添加图片描述

1.实现初始化表格

<template><div class="main-page"><div class="flex-end"><div class="public-search">添加班级</div></div><el-table border :data="tableData" stripe style="width: 100%;" :span-method="objectSpanMethod"><el-table-column label="班级" align="center" prop="class" /><el-table-column label="姓名" align="center" prop="name" /><el-table-column label="课程" align="center" prop="course" /><el-table-column label="备注" align="center" prop="remark" /><el-table-column fixed="right" label="删除学生" align="center"><template #default="scope"><span class="del-btn">删除</span></template></el-table-column><el-table-column fixed="right" label="操作" align="center"><template #default="scope"><span class="add-btn">添加学生</span><span class="del-btn">删除班级</span></template></el-table-column></el-table></div>
</template><script setup>
import { ref } from "vue";const tableData = ref()  //表格数据// 第一列的的索引
const firstIndex = ref([])
// 相同行数名的索引的值
const mergerRowIndex = ref([])
//合并表格列
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {if (![1, 2, 3, 4].includes(columnIndex)) {  // 从0开始数,第2, 3, 4, 5列是需要合并的if (rowIndex === 0) {return {rowspan: firstIndex.value[0],colspan: 1}}if (firstIndex.value[0] > rowIndex && rowIndex > 0) {return {rowspan: 0,colspan: 0}}for (let i = 0; i < firstIndex.value.length; i++) {if (rowIndex === firstIndex.value[i]) {return {rowspan: firstIndex.value[i + 1] - firstIndex.value[i],colspan: 1}}if (firstIndex.value[i + 1] > rowIndex && rowIndex > firstIndex.value[i]) {return {rowspan: 0,colspan: 0}}}}
}
// 查验有无相同行数名的对象,如果知道不同行数名的位置,则记住其位置并且压入
const getMergerRowIndex = () => {// 每次调用这个函数,就需要把之前压入到函数内的值给清空mergerRowIndex.value = []firstIndex.value = []for (let i = 1; i < tableData.value.length; i++) {if (tableData.value[i].class != tableData.value[i - 1].class) {mergerRowIndex.value.push(i);firstIndex.value.push(i);}}//  并且还要压入表格的的长度mergerRowIndex.value.push(tableData.value.length);firstIndex.value.push(tableData.value.length);
}//请求接口获取数据
const getData = () => {let data = [{ id: '1', class: '一班', name: '张三', course: '数学', remark: '数学年级第二', },{ id: '2', class: '一班', name: '李四', course: '语文', remark: '语文还行', },{ id: '3', class: '一班', name: '王五', course: '英语', remark: '英语一般般', },{ id: '4', class: '二班', name: '向小小', course: '语文', remark: '语文年级第一', },{ id: '5', class: '二班', name: '杨六六', course: '数学', remark: '数学年级第一', },]tableData.value = datagetMergerRowIndex()
}
getData()
</script><style lang="scss"  scoped>
.main-page {.flex-end {display: flex;justify-content: end;margin-bottom: 10px;}.add-btn {color: #0077ef;margin-right: 4px;cursor: pointer;}.del-btn {color: #f56c6c;cursor: pointer;}.public-search {background: #0077ef;border-radius: 4px;height: 32px;padding: 0 14px;text-align: center;color: #ffffff;cursor: pointer;align-items: center;display: flex;user-select: none;}
}
</style>

初始化后的页面
在这里插入图片描述

2.实现添加班级与学生的功能

关键代码

//给添加班级与添加学生绑定事件
<div class="public-search" @click="addStudents(null, null)">添加班级</div>
<span class="add-btn" @click="addStudents(scope.$index, scope.row)">添加学生</span>
//为了方便管理数据给新增弹窗重新定义了一个组件AddClass
<AddClass v-model:show="showClass" :row="rowList" :tableData="tableData" @addClass="addClass" /><script>
import AddClass from "./AddClass.vue"; //引入组件const showClass = ref(false)
const rowList = ref()  //行数据
const rowIndex = ref(0)  //点击的多少行//添加学生和班级
const addStudents = (index, row) => {rowIndex.value = index || 0rowList.value = row || {}showClass.value = true
}//添加班级或学生
const addClass = (form) => {//这里全局都是根据class来判断唯一值的,视具体情况而修改let len = tableData.value.filter(res => res.class === form.class).length;if (len === 0) {len = tableData.value.length;}//新增学生的随机idform.id = Math.random()//使用splice(xx,0,{}) 这个方法在指定位置加数据tableData.value.splice(len + rowIndex.value, 0, {...form})getMergerRowIndex()
}
</script>

最后实现的效果
在这里插入图片描述

3.添加的弹窗

<template><div class="add-class"><el-dialog v-model="dialogVisible" title="新增" width="480px" :before-close="closeDialog"><el-form ref="ruleFormRef" :model="ruleForm" label-width="120px" label-position="top" class="demo-ruleForm"><el-form-item label="班级:" prop="class" v-if="!hasClass"><el-select v-model="ruleForm.class" filterable allow-create default-first-option placeholder="请输入或者选择班级"><el-option label="一班" value="一班" /><el-option label="二班" value="二班" /><el-option label="三班" value="三班" /><el-option label="四班" value="四班" /><el-option label="五班" value="五班" /></el-select></el-form-item><el-form-item label="姓名:" prop="name"><el-input v-model="ruleForm.name" /></el-form-item><el-form-item label="课程:" prop="course"><el-input v-model="ruleForm.course" /></el-form-item><el-form-item label="备注:" prop="remark"><el-input v-model="ruleForm.remark" :rows="2" type="textarea" /></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button type="primary" @click="onSubmit">确定</el-button><el-button @click="closeDialog">取消</el-button></span></template></el-dialog></div>
</template><script setup >
import { ref, reactive, defineEmits, defineProps, computed, watch } from "vue"
import { ElMessage } from 'element-plus'
const emits = defineEmits(['update:show']);
const props = defineProps({show: Boolean,row: Object || {},tableData: Array
})
watch(props, () => {if (props.row && props.row.class) {ruleForm.class = props.row.classhasClass.value = true} else {ruleForm.class = ''hasClass.value = false}
})
const hasClass = ref(false) //是否有class
const dialogVisible = computed({get: () => { return props.show },set: newVal => emits('update:show', newVal)
});
const ruleForm = reactive({ class: '',name: '',course: '',remark: '',
})
const ruleFormRef = ref()
const closeDialog = () => {dialogVisible.value = falseruleFormRef.value && ruleFormRef.value.resetFields()
}
const onSubmit = async () => {//如果存在班级则不能继续添加班级if (!hasClass.value) {if (props.tableData.some(res => res.class === ruleForm.class)) {ElMessage.error('已存在该班级');return;}}emits('addClass', ruleForm)closeDialog()
}
</script><style lang="scss" scoped>
.add-class {
}
</style>

新增班级弹窗效果
在这里插入图片描述
新增学生的效果
在这里插入图片描述

4.删除班级

关键代码

   //绑定事件<span class="del-btn" @click="delClass(scope.$index, scope.row)">删除班级</span>import { ElMessage, ElMessageBox } from 'element-plus'
//删除班级
const delClass = (index, row) => {ElMessageBox.confirm(`是否删除班级${row.class}?`,{confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning',}).then(() => {let len = tableData.value.filter(res => res.class === row.class).lengthtableData.value.splice(index, len)getMergerRowIndex()ElMessage({type: 'success',message: '删除成功',})}).catch(() => {ElMessage({type: 'info',message: '取消操作',})})
}

实现效果
请添加图片描述

5.删除学生

关键代码

//绑定事件
<span class="del-btn" @click="delStudents(scope.row)">删除</span>//删除学生
const delStudents = (row) => {ElMessageBox.confirm(`是否删除学生${row.name}?`,{confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning',}).then(() => {tableData.value = tableData.value.filter(item => {return item.id != row.id})getMergerRowIndex()ElMessage({type: 'success',message: '删除成功',})}).catch(() => {ElMessage({type: 'info',message: '取消操作',})})
}

效果图
请添加图片描述

end: 关于修改,其实和新增差不多这里就没有写了,合并表格并实现增删改查的功能就是这些。

全部代码可以关注这里哦

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】哈希表

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 我的gitee&#xff1a;C仓库 个人专栏&#xff1a;C专栏 文章目录 前言一、什么是哈希&#xff1f;二、哈希表的插入及哈希冲突解决哈希冲突的方式1.闭散列的哈希表闭散列哈希表的删除实现&#xff08;重点细节处理&#xf…

LNMP和数据库的安装

LNMP是什么 L&#xff1a;Linux平台&#xff0c;操作系统&#xff0c;另外桑组件的运行平台 N&#xff1a;nginx 提供前端页面 M&#xff1a;MySQL&#xff0c;开源关系的数据库&#xff0c;主要是用来保存用户账号信息。 P&#xff1a;PHP&#xff0c;开发一种动态页面的编程语…

基于 ACK Fluid 的混合云优化数据访问(一):场景与架构

作者&#xff1a;车漾&#xff08;必嘫&#xff09; 本系列文章将介绍如何基于 ACK Fluid 支持和优化混合云的数据访问场景。 概述 在 AI 和大数据时代&#xff0c;算力即正义&#xff0c;强大的算力推动了源源不断的创新。然而&#xff0c;企业自建的算力集群存在资源容量和…

C#中的Dispatcher:Invoke与BeginInvoke的使用

Dispatcher是.NET框架中的一个重要概念&#xff0c;用于处理异步消息传递。在C#中&#xff0c;Dispatcher提供了两种方法&#xff1a;Invoke和BeginInvoke&#xff0c;用于控制线程上消息的顺序和执行方式。 目录 一、Dispatcher.Invoke二、Dispatcher.BeginInvoke三、使用场景…

安卓三防平板在行业应用中有哪些优势

在工业维修和检测中&#xff0c;安卓三防平板的应用也十分广泛。它可以搭载各种专业软件和工具&#xff0c;帮助工人们进行设备故障排查和维护&#xff0c;降低了维修成本和停机时间。 一、产品卖点&#xff1a; 1. 防水性能&#xff1a;该手持平板采用了防水设计&#xff0c;…

基于FPGA的数字时钟系统设计

在FPGA的学习中&#xff0c;数字时钟是一个比较基础的实验案例&#xff0c;通过该实验可以更好的锻炼初学者的框架设计能力以及逻辑思维能力&#xff0c;从而打好坚实的基本功&#xff0c;接下来就开始我们的学习吧&#xff01; 1.数码管介绍 数码管通俗理解就是将8个LED(包含…

什么是UI自动化测试工具?

UI自动化测试工具有着AI技术驱动&#xff0c;零代码开启自动化测试&#xff0c;集设备管理与自动化能力于一身的组织级自动化测试管理平台。基于计算机视觉技术&#xff0c;可跨平台、跨载体执行脚本&#xff0c;脚本开发和维护效率提升至少50%;多端融合统一用户使用体验&#…

C/C++ 线程超详细讲解(系统性学习day10)

目录 前言 一、线程基础 1.概念 2.一个进程中多个线程特征 2.1 线程共有资源 2.2 线程私有资源 3.线程相关的api函数 3.1 创建线程 创建线程实例代码如下&#xff1a; 需要特别注意的是&#xff1a; -lpthread和-pthread的区别 3.2 给线程函数传参 传参实例代码如…

springboot项目Html页面引入css文件不生效

我的出错原因&#xff1a; 在调用css文件时&#xff1a; <link rel"stylesheet" type"text/css" href"/static/css/style.css" /> 这里我多加了一个/static,而使得css样式不生效 因为在springboot项目中&#xff0c;静态资源是默认存…

3D机器视觉:解锁未来的立体视野

原创 | 文 BFT机器人 机器视觉领域一直在不断演进&#xff0c;从最初的二维图像处理&#xff0c;逐渐扩展到了更复杂的三维领域&#xff0c;形成了3D机器视觉。3D机器视觉技术的涌现为计算机系统带来了全新的感知和理解能力&#xff0c;这一领域的发展正日益受到广泛关注。本文…

上海亚商投顾:沪指探底回升 华为汽车概念股集体大涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日探底回升&#xff0c;早盘一度集体跌超1%&#xff0c;随后震荡回暖&#xff0c;深成指、创业板指…

043:mapboxGL鼠标点击提示source属性信息

第043个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中通过鼠标点击提示source属性信息。这里用到了popup弹窗,用到了click事件,用到了鼠标样式的变化等功能。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源…