【sgLazyTree】自定义组件:动态懒加载el-tree树节点数据,实现增删改、懒加载及局部数据刷新。

特性 

  1. 可以自定义主键、配置选项
  2. 支持预定义节点图标:folder文件夹|normal普通样式
  3. 多个提示文本可以自定义
  4. 支持动态接口增删改节点

sgLazyTree源码

<template><div :class="$options.name" v-loading="rootLoading"><div class="tree-header" v-if="!(readonly || readonly === '')"><div class="sg-left "></div><div class="sg-right "><el-button type="text" size="mini" @click.stop="addRoot">{{ (data.text || {}).addRootButtonText|| `添加根节点` }}<i class="el-icon-circle-plus-outline"></i></el-button></div></div><div class="tree-container"><el-tree :load="loadNode" lazy ref="tree" :node-key="mainKey" :props="data.props || { label: 'label' }":icon-class="`${data.iconType}-tree-node`" :indent="data.indent || 25" @current-change="current_change"@node-click="nodeClick" highlight-current><el-popover popper-class="tree-el-popover" placement="right" width="120" trigger="hover" title="" content="":disabled="readonly || readonly === ''" slot-scope="{ node, data }"><span class="right"><el-button title="添加" type="text" size="" icon="el-icon-circle-plus-outline"@click.stop="addNode(node, data)">添加</el-button><el-button title="删除" type="text" size="" icon="el-icon-remove-outline"@click.stop="remove(node, data)">删除</el-button></span><div slot="reference" class="node-label"><label class="left" :title="node.label">{{ node.label }}</label></div></el-popover></el-tree></div></div>
</template><script>
export default {name: 'sgLazyTree',data() {return {// 动态树:增删改_________________________________________________________rootNode: null,//根节点rootResolve: null,//根节点focusNodeId: null,//聚焦高亮新添加IDrootLoading: false,//根节点列表加载mainKey: 'id',//默认主键defaultRootId: 'root',//默认根节点ID就是root// _________________________________________________________}},props: ["data","readonly",],watch: {data: {handler(d) {d.nodeKey && (this.mainKey = d.nodeKey);d.rootId && (this.defaultRootId = d.rootId);}, deep: true, immediate: true,},},methods: {// 动态懒加载树:增删改_________________________________________________________// 加载根节点loadRootNode() {this.rootNode.childNodes = [];this.loadNode(this.rootNode, this.rootResolve);},// 加载常规节点loadNode(node, resolve) {let data = {};if (node.level === 0) {data = { [this.mainKey]: this.defaultRootId };this.rootNode = node;//记录根节点this.rootResolve = resolve;//记录根节点} else {data = node.data;}this.loadNodeData(data, d => {resolve(d);this.rootLoading = false;this.$nextTick(() => { this.focusNode(this.focusNodeId) });});},// 加载节点数据(通过接口向后台获取数据)loadNodeData(data, cb) {let resolve = d => { cb && cb(d) };this.$emit(`loadNode`, data, resolve);},// 聚焦到某一个节点focusNode(id) {if (!id) return;this.$nextTick(() => {this.$refs.tree.setCurrentKey(id);//高亮显示某个节点this.$emit(`currentChange`, this.$refs.tree.getCurrentNode());this.$nextTick(() => {let dom = document.querySelector(`.el-tree-node.is-current`);dom && dom.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });//缓慢滚动});});},// 添加根节点addRoot() { this.addNode(this.$refs.tree.root, { [this.mainKey]: this.defaultRootId }) },// 添加节点addNode(node, data) {let isRootNode = data[this.mainKey] === this.defaultRootId;isRootNode && (this.rootLoading = true);let resolve = d => {this.focusNodeId = d[this.mainKey];//记录加载完毕后需要聚焦的节点IDif (isRootNode) {this.loadRootNode();} else {node.loaded = false; //必须要设置loaded=false,否则第二次展开节点不会触发加载数据node.expanded ? node.loadData() : node.expand();//如果已展开→触发加载,否则就先展开→触发加载 }};this.$emit(`addNode`, data, resolve);},// 删除节点remove(node, data) {this.$confirm((this.data.text || {}).removeConfirmTip || `此操作将永久删除该节点及其下面的节点,是否继续?`,(this.data.text || {}).removeConfirmTitle || `提示`,{dangerouslyUseHTMLString: true,confirmButtonText: `确定`,cancelButtonText: `取消`,type: "warning",}).then(() => {this.removeNodeData(node, data)}).catch(() => { });},// 删除节点数据(通过接口向后台删除数据)removeNodeData(node, data) {node.loading = true;//出现加载动画let resolve = d => {node.loading = false;this.$message.success(`删除成功`);// 从显示界面删除节点let childNodes = node.parent.childNodes;childNodes.splice(childNodes.findIndex(d => d.data[this.mainKey] === data[this.mainKey]), 1);};this.$emit(`removeNode`, data, resolve);},// 当前选中节点变化时触发的事件current_change(d) { this.$emit(`currentChange`, d); },//点击节点nodeClick(d) { this.focusNodeId = null; this.$emit(`nodeClick`, d); },}
};
</script><style lang="scss" scoped>
@import "~@/css/sg";.sgLazyTree {$treeHeaderHeight: 30px;width: 100%;height: 100%;display: flex;flex-wrap: nowrap;flex-direction: column;white-space: nowrap;flex-shrink: 0;flex-grow: 1;position: relative;.tree-header {display: flex;justify-content: space-between;align-items: center;height: $treeHeaderHeight;}.tree-container {position: relative;overflow: auto;box-sizing: border-box;height: calc(100% - #{$treeHeaderHeight});user-select: none;@include scrollbarHover();>>>.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {background-color: #409EFF22; // 高亮当前选中节点背景}>>>.el-tree {* {transition: none;}.el-tree-node__children {min-width: max-content; //这样才会出现水平滚动条}.normal-tree-node,.folder-tree-node {flex-shrink: 0;display: block;padding: 0 !important;margin: 0;width: 20px;height: 20px;margin-right: 5px;background: transparent url("/static/img/fileType/folder/folder.svg") no-repeat center / contain;margin-left: 20px;&~span:not(.el-icon-loading) {width: 100%;.node-label {height: 40px;display: flex;align-items: center;}}&.expanded,&.is-leaf {flex-shrink: 0;transform: rotate(0deg);background-image: url("/static/img/fileType/folder/folder-open.svg");}}}}
}.tree-el-popover {.el-button {padding-top: 0;padding-bottom: 0;}
}
</style>

用例

<template><div style="width: 300px;padding-right: 100px;"><sgLazyTree :data="lazyTreeData" @currentChange="currentChange" @loadNode="loadNode"@addNode="addNode" @removeNode="removeNode" /></div>
</template><script>
import sgLazyTree from "@/vue/components/admin/sgLazyTree";
export default {components: { sgLazyTree, },data() {return {autoId: 0,//自增编号lazyTreeData: {nodeKey: `ID`,//主键props: { label: 'MC' },//配置选项iconType: 'folder',//节点图标:folder文件夹|normal普通样式text: {addRootButtonText: '添加根目录',//添加根节点按钮文本removeConfirmTitle: '警告!!!',//删除节点提示标题removeConfirmTip: '此操作将永久删除该文件夹及其下面的文件,是否继续?',//删除节点提示内容},},}},methods: {// 获取当前聚焦节点的数据currentChange(d) {console.log(`currentChange`, d);},// 加载节点数据loadNode(data, resolve) { this.$d.column_queryByPid({ data: { PID: data.ID }, doing: { s: d => resolve(d) } }); },// 添加节点addNode(data, resolve) {this.$d.column_save({data: {MC: `新增栏目名称(${++this.autoId})`,LX: 0, PID: data.ID,//上一级id}, doing: { s: d => resolve(d) }});},// 删除节点removeNode(data, resolve) {this.$d.column_delete({ data: { ID: data.ID }, doing: { s: d => resolve(d) } });},},};
</script> 

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

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

相关文章

我使用的Vim插件

2023年9月5日&#xff0c;周二下午 为了方便以后还原自己的Vim插件配置&#xff0c;于是写这篇博客来记录一下 不定期更新 目录 语法检查Syntastic文件树The NERD tree自动补全括号auto-pairs超轻量级自动补全vim-auto-popmenu 我使用的插件管理器是vim-plug 语法检查Syntas…

Java学习笔记之----I/O(输入/输出)二

【今日】 孩儿立志出乡关&#xff0c;学不成名誓不还。 文件输入/输出流 程序运行期间&#xff0c;大部分数据都在内存中进行操作&#xff0c;当程序结束或关闭时&#xff0c;这些数据将消失。如果需要将数据永久保存&#xff0c;可使用文件输入/输出流与指定的文件建立连接&a…

GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图

GPT对于每个科研人员已经成为不可或缺的辅助工具&#xff0c;不同的研究领域和项目具有不同的需求。如在科研编程、绘图领域&#xff1a;1、编程建议和示例代码: 无论你使用的编程语言是Python、R、MATLAB还是其他语言&#xff0c;都可以为你提供相关的代码示例。2、数据可视化…

操作系统强化认识之Shell编程学习与总结

目录 1.Shell的概述 2.Shell脚本入门 3.变量 3.1.系统预定义变量 3.2.自定义变量 3.3.特殊变量 4.运算符 5.条件判断 6.流程控制 6.1.if判断 6.2.case语句 6.3.for循环 6.4.while循环 7.read读取控制台输入 8.函数 8.1.系统函数 8.2.自定义函数 9.正则表示式入…

Python,如何安装lap,pip安装lap出现问题

Linux可以&#xff1a; pip install cpython pip install gitgit://github.com/gatagat/lap.gitwindows可以&#xff1a; 下载https://github.com/gatagat/lap 后解压&#xff0c; 安装pip install cpython 安装VS2019企业版&#xff1a; key BF8Y8-GN2QH-T84XB-QVY3B-RC4D…

Python 之 match 表达式

Python 从 3.10 版本开始增加了 match 语句&#xff0c;和其他语言常见的 switch 语句极其相似&#xff0c;但功能更加强大。 本文通过实例&#xff0c;了解下其用法。 基本的 match 语句 def http_code(status): match status: case 400 | 404 | 418: …

1801. 积压订单中的订单总数;1567. 乘积为正数的最长子数组长度;923. 三数之和的多种可能

1801. 积压订单中的订单总数 核心思想&#xff1a;维护一个最小堆sell和一个最大堆buy&#xff0c;然后模拟即可。 1567. 乘积为正数的最长子数组长度 核心思想:动态规划&#xff0c;z表示以当前数字num结尾的乘积为正的最长子数组长度&#xff0c;f表示以当前数字num结尾的乘…

C#循环定时上传数据,失败重传解决方案,数据库标识

有些时候我们需要定时的上传一些数据库的数据&#xff0c;在数据不完整的情况下可能上传失败&#xff0c;上传失败后我们需要定时在重新上传失败的数据&#xff0c;该怎么合理的制定解决方案呢&#xff1f;下面一起看一下&#xff1a; 当然本篇文章只是提供一个思路&#xff0…

postman json复杂数据的模拟

先设置路径 然后可以定义下边数据&#xff08;Key value&#xff09; 也可以不定义 看你的情况 [{"mac": "4C-77-66-19-50-65","addressPattern": "98jd","platform": "ios","registrationId": "…

android studio安卓模拟器高德SDK定位网络连接异常

背景 使用了高德SDK创建了一个 project, 下面是运行界面: 点击 "开始定位"按钮, 结果并没有返回定位信息, 而是报错了: 根据错误提示打开这个网址: https://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode, 并且找到错误码 4 的信息, 显示的是网…

【transformer】自注意力源码解读和复杂度计算

Self-attention A t t e n t i o n ( Q , K , V ) s o f t m a x ( Q K T d k ) V Attention(Q,K,V) softmax(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)softmax(dk​ ​QKT​)V 其中&#xff0c; Q Q Q为查询向量&#xff0c; K K K和 V V V为键向量和值向量&#xff0c;…

油田钻井平台三维应急仿真系统降低事故发生概率

海上钻井是供海上作业人员进行生产作业或者其他活动使用的仿陆地区域&#xff0c;被称为“流动的国土”&#xff0c;主要由上部平台、下浮体(沉垫浮箱)和中部立柱三部分组成&#xff0c;平台上安装钻井、动力、通讯、导航等设备&#xff0c;以及安全救生和人员生活等设施&#…

OB Cloud 初体验

文章来源&#xff1a;韩锋频道 韩锋 数据库行业资深从业者&#xff0c;著有《SQL 优化最佳实践》、《数据库高效优化》等数据库相关著作。 OceanBase&#xff08;下文简称OB&#xff09; 作为国内一款优秀的分布式数据库&#xff0c;这些年来发展很快&#xff0c;在金融、电商…

Java之文件操作与IO

目录 一.认识文件 1.1文件是什么&#xff1f; 1.2文件的组织 1.3文件路径 1.4文件的分类 二.文件操作 2.1File概述 三.文件内容操作--IO 3.1JavaIO的认识 3.2Reader和Writer ⭐Reader类 ⭐Writer类 3.2FileInputStream和FileOutputStream ⭐FileInputStream类 …

继承(个人学习笔记黑马学习)

1、基本语法 #include <iostream> using namespace std; #include <string>//普通实现页面//Java页面 //class Java { //public: // void header() { // cout << "首页、公开课、登录、注册...(公共头部)" << endl; // } // void footer() …

【广州华锐互动】VR全景工厂虚拟导览,虚拟现实技术提升企业数字化信息管理水平

随着工业4.0的到来&#xff0c;VR工厂全景制作成为了越来越多工业企业的选择。传统的工厂管理方式往往存在诸多问题&#xff0c;如信息不对称、安全隐患等。为了解决这些问题&#xff0c;VR工厂全景制作应运而生&#xff0c;它通过结合虚拟现实现实技术和数据采集技术&#xff…

设计模式-迭代器

文章目录 1. 引言1.1 概述1.2 设计模式1.3 迭代器模式的应用场景1.4 迭代器模式的作用 2. 基本概念2.1 迭代器 Iterator2.2 聚合 Aggregate2.3 具体聚合 ConcreteAggregate 3. Java 实现迭代器模式3.1 Java 集合框架3.2 Java 迭代器接口3.3 Java 迭代器模式实现示例 4. 迭代器模…

Android 音频框架 基于android 12

文章目录 前言音频服务audioserver音频数据链路hal 提供什么样的作用 前言 Android 的音频是一个相当复杂的部分。从应用到框架、hal、kernel、最后到硬件&#xff0c;每个部分的知识点都相当的多。而android 这部分代码在版本之间改动很大、其中充斥着各种workaround的处理&a…

介绍GitHub

GitHub 是一个基于互联网的源代码托管平台&#xff0c;可以帮助软件开发者存储和管理源代码&#xff0c;方便团队协作和版本控制。GitHub 的主要功能包括&#xff1a; 代码托管&#xff1a;开发者可以在 GitHub 上创建远程代码仓库&#xff0c;存储和管理他们的源代码。 版本控…

聚观早报|多邻国推出进阶英文课程;电动汽车成本将高于燃油车

【聚观365】9月5日消息 多邻国即将推出进阶英文课程 未来电动汽车成本仍将高于燃油车 戴尔科技2024财年第二季度营收229亿美元 现代汽车电动汽车销量在8月份环比继续下滑 马斯克称将用X数据训练AI 多邻国即将推出进阶英文课程 语言学习平台多邻国宣布&#xff0c;为了满…