15.树形虚拟列表实现(支持10000+以上的数据)el-tree(1万+数据页面卡死)

1.问题使用el-tree渲染的树形结构,当数据超过一万条以上的时候页面卡死

2.解决方法:

使用vue-easy-tree来实现树形虚拟列表,注意:vue-easy-tree需要设置高度

3.代码如下

<template><div class="ve-tree" style="height:calc(100vh - 20px)"><!-- 不使用虚拟滚动时只需去掉height参数即可 --><vue-easy-treeref="veTree"node-key="id"show-checkboxheight="calc(100vh - 20px)":data="treeData":props="props"></vue-easy-tree></div></template><script>import VueEasyTree from "@wchbrad/vue-easy-tree";
// 样式文件,可以根据需要自定义样式或主题(使用这个样式需要装sass-loader以及node-sass)
import "@wchbrad/vue-easy-tree/src/assets/index.scss"export default {components: {VueEasyTree},data() {return {props: {label: "name",children: "children"},treeData: []};},created() {const data = [],root = 8,children = 3,base = 1000;for (let i = 0; i < root; i++) {data.push({id: `${i}`,name: `test-${i}`,children: []});for (let j = 0; j < children; j++) {data[i].children.push({id: `${i}-${j}`,name: `test-${i}-${j}`,children: []});for (let k = 0; k < base; k++) {data[i].children[j].children.push({id: `${i}-${j}-${k}`,name: `test-${i}-${j}-${k}`});}}}this.treeData = data;}};</script>

4. 使用方法,首先安装依赖

yarn add @wchbrad/vue-easy-tree

如果不引入样式文件可以不安装(sass-loader以及node-sass)
node-sass:4.14.1
sass-loader:8.0.2
(自己安装的时候失败了,所以选择不引入样式文件)

5.组件引入

import VueEasyTree from "@wchbrad/vue-easy-tree";
// 样式文件,可以根据需要自定义样式或主题
import "@wchbrad/vue-easy-tree/src/assets/index.scss"export default {components: {VueEasyTree}
}

6.功能列表

 1.大数据量支持虚拟滚动2.基本树形数据的展示3.支持checkbox选择4.支持懒加载5.默认展开和默认选中6.禁用节点7.通过多种方式选中节点和获取选中的节点信息8.支持自定义节点内容9.支持节点过滤10.非虚拟滚动下,支持手风琴模式11.非懒加载时,支持节点拖拽

支持与element-ui完全相同的主题样式更换,提供与element-ui相同的图标供选用
如果使用element-ui的默认属性代码为

<template><div class="tree-comp"><div class="input-box"><el-input size="mini" suffix-icon="el-icon-search" clearable v-model="filterInputValue"@change="onFilter" placeholder="请输入检索内容"></el-input></div><div class="ve-tree" style="height:520px"><!-- 不使用虚拟滚动时只需去掉height参数即可 --><vue-easy-treev-for="(treeItem, index) in treeOption" :key="index"ref="treeComp"node-key="id"show-checkboxheight="520px":data="treeItem.treeData":props="props":filter-node-method="filterNode":highlight-current="true":default-checked-keys="allNodeIds":default-expanded-keys="defaultExpandedKeys[index]":check-on-click-node="true"v-bind="treeItem.defaultProps"v-on="treeItem.defaultActions"@check-change="handleCheckChange"></vue-easy-tree></div></div>
</template><script>
import VueEasyTree from "@wchbrad/vue-easy-tree";
const debounce = function debounce(fn, delay) {let timer = null;return function () {clearTimeout(timer);let args = arguments;let that = this;timer = setTimeout(function () {fn.apply(that, args);}, delay);};
};
export default {name: 'TreeComp',props: {treeOption: { type: Array },selection: {type: String,default: 'multiple'}},components: {VueEasyTree},data() {return {filterInputValue: '',  // 过滤搜素值curChoosedData: {} ,    // 当前节点数据filterParentNodeId: [],selectedCount: 0,defaultExpandedKeys: [],allNodeIds: [],props: {label: "name",children: "children"},treeData: []}},watch: {curChoosedData(val){this.$emit('curChoosedDataChange', val);},},computed: {isSingle() {return this.selection === 'single'}},created(){const data = [],root = 8,children = 3,base = 9000;for (let i = 0; i < root; i++) {data.push({id: `${i}`,name: `test-${i}`,children: []});for (let j = 0; j < children; j++) {data[i].children.push({id: `${i}-${j}`,name: `test-${i}-${j}`,children: []});for (let k = 0; k < base; k++) {data[i].children[j].children.push({id: `${i}-${j}-${k}`,name: `test-${i}-${j}-${k}`});}}}this.treeData = data;},mounted() {this.getSelectedCount()},methods: {expandedLevel(num = 1){const treeCompRef = this.$refs.treeComp;this.treeOption.forEach((item)=>{item.treeData = this.$lodash.cloneDeep(item.treeData)})if(treeCompRef && treeCompRef.length > 0) {for (const [index,item] of treeCompRef.entries()) {let checkedKeys = item.getCheckedKeys()let treeData = item.datathis.defaultExpandedKeys[index] = this.expandedReduce(treeData, num)item.setCheckedKeys(checkedKeys)}}},//递归获取展开层级的idexpandedReduce(list,deep = 1){return deep > 0 ? list.reduce((val ,next)=>{return next.children? val.concat(next.id).concat(this.expandedReduce(next.children,deep-1)) : val.concat(next.id)},[]) : []},// 过滤值改变触发filterNodeonFilter(filterVal) {const treeCompRef = this.$refs.treeComp;if(treeCompRef && treeCompRef.length >0){for (let item of treeCompRef) {this.filterParentNodeId = [];item.filter(filterVal);}}},// 筛选树节点filterNode(value, data) {if (!value) return true;let filterValue = value.split(',');let flag = false;filterValue.forEach((item) => {if (data.name.indexOf(item) !== -1 || this.filterParentNodeId.includes(data.parentId)) {this.filterParentNodeId.push(data.id);flag = true;} });return flag;},handleCheckChange:function (data, checked) {if (this.isSingle) {this.singleCheck(data,checked)}this.getSelectedCount()},singleCheck:debounce(function (data,checked){this.$nextTick(()=>{if (checked) {this.$refs.treeComp[0].setCheckedKeys([data.id]);}})},100),getSelectedCount: debounce(function () {this.selectedCount = 0const treeCompRef = this.$refs.treeComp;if(treeCompRef && treeCompRef.length >0){for (const item of treeCompRef) {let selectedNodes = item.getCheckedNodes()let selectedChildrenNodes = selectedNodes.filter((node) => {// !Object.prototype.hasOwnProperty.call(node, 'children')// return node.children.length === 0return !node.children || node.children.length === 0})this.selectedCount += selectedChildrenNodes.length}}this.$emit('getSelectedCount', this.selectedCount)},300)}
}
</script>
<style scoped>.tree-comp {display: flex;flex-direction: column;overflow: hidden;width: 100%;height: 100%;}.tree-comp .input-box >>> .el-input__inner {border: none;border-radius: 0;border-bottom: 1px solid #A8AED3;height: 32px;line-height: 32px;}.tree-comp .input-box >>> .el-input__suffix-inner {line-height: 32px;font-size: 16px;}.tree-comp .el-tree {/* flex: 1; */max-height: 100%;overflow-y: auto;}.tree-node {flex: 1;height: 30px;line-height: 30px;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;/*background: #fff;*/z-index: 2;}.tree-self {width: 100%;overflow: scroll;}.tree-self >>> .el-tree-node {min-width: 100%;display: table;}
</style>

7.效果

在这里插入图片描述

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

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

相关文章

《web应用技术》第12次课后作业

1、了解servlet技术 Servlet(server applet)&#xff1a;运行在服务器的小程序&#xff0c;Servlet就是一个接口&#xff0c;定义了Java类被浏览器访问到的规则。将来我们自定义一个类&#xff0c;实现Servlet接口&#xff0c;复写方法。 Servlet本身不能独立运行&#xff0c…

2024广东省职业技能大赛云计算赛项实战——OpenStack搭建

OpenStack搭建 前言 搭建采用双节点安装&#xff0c;即controller控制节点和compute计算节点。 CentOS7 系统选择 2009 版本&#xff1a;CentOS-7-x86_64-DVD-2009.iso 可从阿里镜像站下载&#xff1a;https://mirrors.aliyun.com/centos/7/isos/x86_64/ OpenStack使用竞赛培…

JaveEE进阶----Spring Web MVC入门

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、什么是 Spring Web MVC&#xff1f;&#xff1f;1.1MVC 定义1.2 什么是Spring MVC ?1.3过浏览器和用户程序交互 二、 RequestMapping 注解三、Postman 前言…

Python中栈的实现与应用

Python中栈的实现与应用 一、引言 栈&#xff08;Stack&#xff09;是一种重要的数据结构&#xff0c;它遵循后进先出&#xff08;LIFO&#xff0c;Last In First Out&#xff09;的原则。栈的基本操作包括入栈&#xff08;push&#xff09;和出栈&#xff08;pop&#xff09…

容器基本概念_从虚拟化技术_到容器化技术_开通青云服务器_并远程连接_容器安装---分布式云原生部署架构搭建007

这一部分,属于以前都会用到的,会快速过一遍,对于关键技术问题会加以说明 https://www.yuque.com/leifengyang/oncloud文档地址在这里,可以看,有些命令可以复制使用 可以看到容器的出现就是 目的就是,让你做的所有的软件,都可以一键部署启动 打包就是docker build 然后: 对于…

关于后端幂等性问题分析与总结

后端幂等性&#xff08;Idempotency&#xff09;是指对系统执行一次操作或多次执行相同的操作&#xff0c;其结果始终如一。在分布式系统和API设计中&#xff0c;这是一个关键概念&#xff0c;因为它能保证用户无论请求被路由到哪个节点&#xff0c;多次执行相同的请求都不会导…

陈晓婚前婚后大变样

陈晓婚前婚后大变样&#xff1f;陈妍希揭秘甜蜜与现实的碰撞在娱乐圈的星光璀璨中&#xff0c;有一对夫妻总是津津乐道&#xff0c;那就是陈晓和陈妍希。他们的爱情故事&#xff0c;从荧幕到现实&#xff0c;一直备受关注。然而&#xff0c;近日陈妍希在节目中透露&#xff0c;…

22、架构-资源与调度

1、资源与调度 调度是容器编排系统最核心的功能之一&#xff0c;“编排”一词本身便包 含“调度”的含义。调度是指为新创建的Pod找到一个最恰当的宿主机 节点来运行它&#xff0c;这个过程成功与否、结果恰当与否&#xff0c;关键取决于容器 编排系统是如何管理与分配集群节点…

Hadoop 面试题(一)

1. 简述Hadoop核心组件 &#xff1f; Hadoop是一个开源的分布式计算平台&#xff0c;其核心组件主要包括以下几个方面&#xff1a; HDFS (Hadoop Distributed File System)&#xff1a; 一个分布式文件系统&#xff0c;用于在廉价的硬件上存储和管理大量数据。 MapReduce&…

Elasticsearch**Elasticsearch自定义插件开发入门

Elasticsearch作为一个强大的搜索引擎和数据分析工具&#xff0c;其强大的扩展性是其受欢迎的重要原因之一。自定义插件开发入门** Elasticsearch作为一个强大的搜索引擎和数据分析工具&#xff0c;其强大的扩展性是其受欢迎的重要原因之一。通过自定义插件&#xff0c;用户可…

QT设计模式:备忘录模式

备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型设计模式&#xff0c;主要用于保存一个对象当前的状态&#xff0c;并在需要时恢复该状态。它常应用于以下场景&#xff1a; 撤销操作&#xff1a;如文本编辑器撤销、软件开发中的版本控制等&#xff0c;用户可以…

差分总结(一维+二维)

差分&#xff0c;可以视作前缀和的逆运算。 前缀和用于去求一个区间段的和 差分用于改变一个区间的值&#xff08;比如说某个区间都加上或者减去一个数&#xff09; P2367 语文成绩 #include<bits/stdc.h> using namespace std; #define int long long int n,p; int a…

RabbitMQ 学习笔记

RabbitMQ学习笔记 一些概念 Broker &#xff1a;RabbitMQ服务。 virtual host&#xff1a; 其实就是分组。 Connection&#xff1a;连接&#xff0c;生产者消费者与Broker之间的TCP连接。 Channel&#xff1a;网络信道&#xff0c;轻量级的Connection&#xff0c;使用Chann…

2024广东省职业技能大赛云计算赛项实战——Minio服务搭建

Minio服务搭建 前言 这道题是比赛时考到的&#xff0c;没找到具体题目&#xff0c;但在公布的样题中找到了&#xff0c;虽然很短~ 使用提供的 OpenStack 云平台&#xff0c;申请一台云主机&#xff0c;使用提供的软件包安装部署 MINIO 服务并使用 systemctl 管理 Minio是一个…

HTML静态网页成品作业(HTML+CSS)——手机电子商城网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

Vue 封装组件之Input框

封装Input组件:MyInput.vue <template><div class"base-input-wraper"><el-inputv-bind"$attrs"v-on"$listeners"class"e-input":style"inputStyle":value"value":size"size"input&quo…

深入解析微软Edge浏览器:探索其功能与应用

微软Edge浏览器是微软公司推出的一款现代化网页浏览器,旨在为用户提供快速、安全和高效的上网体验。本文将全面解析微软Edge浏览器,从其历史背景、核心功能、性能表现、安全特性到实际应用场景,带领读者深入了解这款浏览器的优势和使用技巧。 一、Edge浏览器的历史背景 1.…

python API自动化(Pytest+Excel+Allure完整框架集成+yaml入门+大量响应报文处理及加解密、签名处理)

1.pytest数据参数化 假设你需要测试一个登录功能&#xff0c;输入用户名和密码后验证登录结果。可以使用参数化实现多组输入数据的测试: 测试正确的用户名和密码登录成功 测试正确的用户名和错误的密码登录失败 测试错误的用户名和正确的密码登录失败 测试错误的用户名和密码登…

转换普通文件为Spring中的MultipartFile类型:处理不同文件格式

在Web开发中&#xff0c;处理文件上传是一个常见的需求。有时&#xff0c;我们需要将普通的文件对象&#xff08;如.txt或.xlsx文件&#xff09;转换为Spring框架中的MultipartFile类型&#xff0c;以便在Controller中处理文件上传和处理。本文将介绍如何在Java中进行这种转换&…

2024广东省职业技能大赛云计算赛项实战——chkrootkit安装与使用

chkrootkit安装与使用 前言 在今年比赛中有考到这样一道题&#xff0c;也是在公布的样卷中找到了它&#xff0c;今天就做做它并讲解一下&#xff1a; 公有云安全&#xff1a;入侵检测系统 使用提供的 makechk.tar.gz 包安装 chkrootkit 入侵检测工具&#xff0c;安装完毕后使…