树状表格子节点移动 - 在Vue.js中实现上下移动子节点的表格功能

目录

功能介绍

示例

代码

视图部分

逻辑部分

完整代码


功能介绍

        本文介绍了如何在Vue.js框架下实现一个树状表格,其中支持选择子节点行的上下移动。通过这个功能,用户可以方便地改变子节点的顺序。代码示例和详细的实现步骤将展示如何使用Vue.js的相关特性和组件实现这个功能。通过本文的介绍,您可以轻松了解如何在您的Vue.js项目中应用这个功能,以满足您的特定需求。     

示例

代码

视图部分

        实现父节点选择的代码

        在上次选中父节点的代码基础上加上操作行,生成上下移动的按钮: 

      <el-table-column align="center"><template slot-scope="scope" v-if="!scope.row.children"><el-button v-show="!validateOperate(scope.row, 'up')" size="mini" icon="el-icon-top" plain@click="handleSort(scope.row, 'up')"></el-button><el-button v-show="!validateOperate(scope.row, 'down')" size="mini" icon="el-icon-bottom" plain@click="handleSort(scope.row, 'down')"></el-button></template></el-table-column>

        新增列定义,用于显示上移和下移按钮。<template> 标签中定义了使用 slot-scope 来访问作用域插槽,在这个作用域下,使用了两个 <el-button> 元素来展示上移和下移按钮。为了使第一行与最后一行只有下移或上移,这里通过绑定 v-show 来控制按钮的显示与隐藏,根据 validateOperate() 方法的返回值确定按钮是否可见。@click 侦听器则会触发 handleSort() 方法来完成所在行的移动。

逻辑部分

组件数据和选中父节点的代码相同,获取tableData后,如果没有index,则自己遍历加上该属性。

   

methods对象新增方法:

  • getParent(id) 方法用于获取拥有指定子行 id 的父级行,它通过遍历 this.tableData 数组来寻找子行所属的父行。
    getParent(id) {let result = [];this.tableData.some(item => {item.children.some(d => {if (d.id == id) result = item;})});return result;}
  • validateOperate(row, type) 方法用于根据指定的操作类型(上移或下移)检查当前行是否可进行该操作。首先判断是否最内层的子树,对于上移操作,当前行的索引为0时返回true,隐藏上移按钮;对于下移操作,当前行的索引等于自身所处children数组的长度减1时返回true,隐藏下移按钮。
    validateOperate(row, type) {if (!row.children) {if (type == 'up' && row.index == 0) {return true;}else if (type == 'down') {return this.getParent(row.id).children.length - 1 == row.index;}else {return false;}}}
  • handleSort(row, type) 方法用于处理行的上移和下移操作。它首先获取该行的父级行和父级行的 ID,并定义一个标志变量 downFlag。然后通过遍历 parent.children 数组来查找需要进行上移或下移操作的行,并进行相应的移动和调整索引的操作。最后,更新父级行的子行列表和相关数据。
    handleSort(row, type) {let parent = this.getParent(row.id);let parentId;let downFlag = true;this.tableData.forEach(item => {if (item.children === parent) parentId = item.id;});console.log(parent);parent.children.some(item => {if (type == 'up') {if (item.index == row.index - 1) {parent.children.splice(row.index, 1);parent.children.splice(item.index, 0, row);parent.children.forEach((child, index) => child.index = index);this.tableData.forEach(data => {if (data.id === parentId) data.children = parent.children;});}} else if (type == 'down' && downFlag) {if (item.index == row.index + 1) {parent.children.splice(row.index, 1);parent.children.splice(item.index, 0, row);parent.children.forEach((child, index) => child.index = index);this.tableData.forEach(data => {if (data.id === parentId) data.children = parent.children;});downFlag = false;}}})}

完整代码

<template><div><el-table v-loading="loading" :data="tableData" style="width: 100%;margin: 20px;" row-key="id" borderdefault-expand-all :tree-props="{ children: 'children' }"><el-table-column width="60" align="center"><template slot="header" slot-scope="scope"><el-checkbox :indeterminate="isIndeterminate" v-model="isFullChecked" @change="checkAllChange"></el-checkbox></template><template slot-scope="{row}" v-if="row.children"><el-checkbox :indeterminate="row.isIndeterminate" :value="row.checked" @change="checkRowChange(row)"></el-checkbox></template></el-table-column><el-table-column prop="series" label="系列" align="center"></el-table-column><el-table-column prop="num" label="编号" align="center"></el-table-column><el-table-column prop="name" label="名字" align="center"></el-table-column><el-table-column align="center"><template slot-scope="scope" v-if="!scope.row.children"><el-button v-show="!validateOperate(scope.row, 'up')" size="mini" icon="el-icon-top" plain@click="handleSort(scope.row, 'up')"></el-button><el-button v-show="!validateOperate(scope.row, 'down')" size="mini" icon="el-icon-bottom" plain@click="handleSort(scope.row, 'down')"></el-button></template></el-table-column></el-table></div>
</template><script>
export default {data() {return {isFullChecked: false,isIndeterminate: false,loading: true,tableData: []}},mounted() {this.getList()},watch: {tableData() {this.isFullChecked = false;this.isIndeterminate = false;}},methods: {getList() {const tableData = [{id: 1,series: 'DDLC',children: [{id: 11,num: '1',name: 'monika',index: 0,},{id: 12,num: '2',name: 'nasuki',index: 1,},{id: 13,num: '3',name: 'sayori',index: 2,},{id: 14,num: '4',name: 'yuri',index: 3,}]},{id: 2,series: 'Bloom Into You',children: [{id: 21,num: '11',name: 'nanami',index: 0,},{id: 22,num: '12',name: 'yuu',index: 1,}]},];tableData.forEach(item => {item.checked = false;item.isIndeterminate = false;})this.tableData = tableData;this.total = this.tableData.length;this.loading = false;},checkAllChange() {const recursionSetChecked = (item, checked) => {item.checked = checked;item.isIndeterminate = false;}this.isIndeterminate = false;this.tableData.forEach(item => recursionSetChecked(item, this.isFullChecked));},checkRowChange(data) {data.checked = !data.checked;const recursion = node => {if (node.children && node.children.length > 0)node.isIndeterminate = false;return node;};this.tableData.forEach(item => recursion(item));if (this.tableData.every(item => item.checked)) {this.isFullChecked = true;}else if (this.tableData.every(item => !item.checked)) {this.isFullChecked = false;}this.isIndeterminate = this.tableData.some(item => item.isIndeterminate)? true: this.tableData.some(item => !item.checked) && this.tableData.some(item => item.checked);},getParent(id) {let result = [];this.tableData.some(item => {item.children.some(d => {if (d.id == id) result = item;})});return result;},validateOperate(row, type) {if (!row.children) {if (type == 'up' && row.index == 0) {return true;}else if (type == 'down') {return this.getParent(row.id).children.length - 1 == row.index;}else {return false;}}},handleSort(row, type) {let parent = this.getParent(row.id);let parentId;let downFlag = true;this.tableData.forEach(item => {if (item.children === parent) parentId = item.id;});console.log(parent);parent.children.some(item => {if (type == 'up') {if (item.index == row.index - 1) {parent.children.splice(row.index, 1);parent.children.splice(item.index, 0, row);parent.children.forEach((child, index) => child.index = index);this.tableData.forEach(data => {if (data.id === parentId) data.children = parent.children;});}} else if (type == 'down' && downFlag) {if (item.index == row.index + 1) {parent.children.splice(row.index, 1);parent.children.splice(item.index, 0, row);parent.children.forEach((child, index) => child.index = index);this.tableData.forEach(data => {if (data.id === parentId) data.children = parent.children;});downFlag = false;}}})}}
}
</script>

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

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

相关文章

基于YOLOv8模型和DarkFace数据集的黑夜人脸检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型和DarkFace数据集的黑夜人脸检测系统可用于日常生活中检测与定位黑夜下的人脸&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目…

【教程】部署apprtc服务中安装google-cloud-cli组件的问题及解决

#0# 前置条件 已经安装完成node&#xff0c;grunt&#xff0c;node 组件和python pip包等。需要安装google-cloud-cli组件。 Ubuntu安装google-cloud-cli组件 apprtc项目运行需要google-cloud-cli前置组件&#xff0c;且运行其中的dev_appserver.py。 根据google官方的关于安…

DC/DC开关电源学习笔记(三)开关频率和储能元件

&#xff08;三&#xff09;开关频率和储能元件 1.开关频率2.储能元件 1.开关频率 频率是开关电源的一个基本属性&#xff0c;它代表了直流电压开启和关断的速率。了解开关频率就可以了解实际应用中电源线路的工作原理。 开关电源利用开关动作将直流电转换为特定频率的脉冲电…

ant-vue1.78版a-auto-complete表单自动搜索返回列表中的关键字标红

a-auto-complete表单自动搜索返回列表中的关键字标红 通常在做关键字标红的场景&#xff0c;都是后端返回html结构&#xff0c;前端直接渲染实现&#xff0c;但是如果需要前端处理的话&#xff0c;实现也是很简单的&#xff0c;接下来我直接上应用场景吧 应用场景就是通过关键…

理解TiDB集群的P99计算方式

原文来源&#xff1a; https://tidb.net/blog/c38dd8ac 一、背景简介 在学习prometheus时&#xff0c;会遇到一个histogram_quantile()函数&#xff0c;用于对histogram类型的指标进行分位数计算&#xff0c;实际上这个函数就是histogram这个指标类型最常用的函数。 此函数…

jq插件:jqgrid和validform的二次封装

做久了vue和react框架项目&#xff0c;偶尔也需要做做原生的项目。不可否认vue的双向绑定机制确实很香&#xff0c;但是也是建立在原生js基础上。所以&#xff0c;只有做更多的原生js项目&#xff0c;才能更加了解vue框架的底层原理。在日常开发中&#xff0c;也会不可避免的会…

mybatis:动态sql【2】+转义符+缓存

目录 一、动态sql 1.set、if 2.foreach 二、转义符 三、缓存cache 1. 一级缓存 2. 二级缓存 一、动态sql 1.set、if 在update语句中使用set标签&#xff0c;动态更新set后的sql语句&#xff0c;&#xff0c;if作为判断条件。 <update id"updateStuent" pa…

jmeter+ant+jenkins接口自动化测试框架

大致思路&#xff1a;Jmeter可以做接口测试&#xff0c;也能做压力测试&#xff0c;而且是开源软件&#xff1b;Ant是基于Java的构建工具&#xff0c;完成脚本执行并收集结果生成报告&#xff0c;可以跨平台&#xff0c;Jenkins是持续集成工具。将这三者结合起来可以搭建一套We…

火山引擎云调度GTM“同城容灾”与“异地多活”实践

随着企业不断推进数字化进程&#xff0c;高并发业务和海量数据的挑战也随之而来。在现实生活中&#xff0c;除了地震、台风、挖光纤这种小概率事件&#xff0c;还有很多人为造成的高概率数据丢失事件&#xff0c;比如人为操作失误、硬件故障、网络攻击等等&#xff0c;故障容灾…

vue可编辑表格

内容包含:校验。下拉框。输入框。日期控件 效果图 1.代码目录 2.index.js import SjjEditable from ./src/editable.vue // import Vue from vueSjjEditable.install = function (Vue) {Vue.component(SjjEditable.name, SjjEditable) }export default SjjEditable 3.util…

【进阶篇】MySQL 存储引擎详解

文章目录 0.前言1.基础介绍2.1. InnoDB存储引擎底层原理InnoDB记录存储结构和索引页结构InnoDB记录存储结构&#xff1a;InnoDB索引页结构&#xff1a; 3. MVCC 详解3.1. 版本号分配&#xff1a;3.2. 数据读取&#xff1a;3.3. 数据写入&#xff1a;3.4. 事务隔离级别&#xff…

【ubuntu】 20.04 网络连接器图标不显示、有线未托管、设置界面中没有“网络”选项等问题解决方案

问题 在工作中 Ubuntu 20.04 桌面版因挂机或不当操作&#xff0c;意外导致如下问题 1、 Ubuntu 网络连接图标消失 2、 有线未托管 上图中展示的是 有线 已连接 &#xff0c;故障的显示 有线 未托管 或其他字符 3、 ”设置“ 中缺少”网络“选项 上图是设置界面&#xff0c…

【Cesium创造属于你的地球】实现地球展示、灵活进行坐标转换、视角切换

大家好&#xff0c;我是AIC山鱼&#xff01;&#x1f449;这是我的主页 &#x1f40b;作为CSDN博主和前端优质创作者✍&#xff0c;我致力于为大家带来新颖、脱俗且有趣的内容。 &#x1f431;我还创建了山鱼社区&#xff0c;这是一个独特的社区&#x1f3e0;&#xff0c;&…

供水营业收费管理系统:智慧水务的得力助手

随着我国经济的快速发展&#xff0c;城市化进程不断加快&#xff0c;供水行业的需求也不断增长。为满足人们日益增长的用水需求&#xff0c;提高供水企业的管理水平和服务质量&#xff0c;供水营业收费管理系统应运而生&#xff0c;成为智慧水务的得力助手。 一、供水营业收费管…

【Hadoop】HDFS读写流程和客户端命令使用

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的…

ChromeOS 的 Linux 操作系统和 Chrome 浏览器分离

科技媒体 Ars Technica 报道称&#xff0c;谷歌正在将 ChromeOS 的浏览器从操作系统中分离出来 —— 让它变得更像 Linux。虽然目前还没有任何官方消息&#xff0c;但这项变化可能会在本月的版本更新中推出。 据介绍&#xff0c;谷歌将该项目命名为 "Lacros"—— 代表…

python爬虫12:实战4

python爬虫12&#xff1a;实战4 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 申明 ​ 本系列所涉及的代码仅用于个人研究与讨论&#xff0c;并不会对网站产生不好…

Hadoop Hdfs基本命令

0目录 1.hadoop安装问题处理 2.hdfs基本命令 3.上传/下载文件和文件夹 1.hadoop安装问题处理 如果安装有进程无法启动&#xff0c;如下图 重新检查6个配置文件 Core-site.xml \ hdfs-site.xml \ hadoop-env.sh \ yarn-site.xml \ workers \ yarn-site.xml 来到hadoop313目录…

SpringBoot 跨域问题和解决方法

Spring Boot 是一种用于构建独立的、生产级别的Java应用程序的框架。在开发Web应用程序时&#xff0c;经常会遇到跨域资源共享&#xff08;CORS&#xff09;问题。本文将详细介绍Spring Boot中的跨域问题以及相应的解决方法。 目录 什么是跨域&#xff1f;1. 使用Spring Boot…

Matlab论文插图绘制模板第109期—特征渲染的标签气泡散点图

在之前的文章中&#xff0c;分享了Matlab标签散点图的绘制模板&#xff1a; 特征渲染的标签散点图&#xff1a; 进一步&#xff0c;再来分享一下特征渲染的标签气泡散点图的绘制模板&#xff0c;从而可以再添加一个维度的信息。 先来看一下成品效果&#xff1a; 特别提示&…