element中Tree 树形控件实现多选、展开折叠、全选全不选、父子联动、默认展开、默认选中、默认禁用、自定义节点内容、可拖拽节点、手风琴模式

目录

  • 1.代码实现
  • 2. 效果图
  • 3. 使用到的部分属性说明
  • 4. 更多属性配置查看element官网

1.代码实现

 <template>
  <div class="TreePage">
    <el-checkbox
      v-model="menuExpand"
      @change="handleCheckedTreeExpand($event, 'menu')"
      >展开/折叠</el-checkbox
    >
    <el-checkbox
      v-model="menuNodeAll"
      @change="handleCheckedTreeNodeAll($event, 'menu')"
      >全选/全不选</el-checkbox
    >
    <el-checkbox
      v-model="menuCheckStrictly"
      @change="handleCheckedTreeConnect($event, 'menu')"
      >父子联动</el-checkbox
    >

    <el-row :gutter="20" style="margin-top: 20px">
      <!--村数据-->
      <el-col :span="24">
        <div class="head-container">
          <el-input
            v-model="deptName"
            placeholder="请输入名称"
            clearable
            size="small"
            prefix-icon="el-icon-search"
            style="margin-bottom: 20px"
          />
        </div>
        <!-- 组织树 -->
        <div class="head-container">
          <el-tree
            ref="menu"
            :props="defaultProps"
            :default-expanded-keys="defaultExpandedKeys"
            :default-checked-keys="defaultCheckedKeys"
            :expand-on-click-node="false"
            :data="menuOptions"
            show-checkbox
            node-key="deptId"
            :check-strictly="!menuCheckStrictly"
            empty-text="加载中,请稍后"
            :filter-node-method="filterNode"
            @node-click="handleNodeClick"
            draggable
            @node-drag-start="handleDragStart"
            @node-drag-enter="handleDragEnter"
            @node-drag-leave="handleDragLeave"
            @node-drag-over="handleDragOver"
            @node-drag-end="handleDragEnd"
            @node-drop="handleDrop"
            :allow-drop="allowDrop"
            :allow-drag="allowDrag"
          >
            <!--自定义节点内容: 使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据。 -->
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>{{ node.label }}</span>
              <span>
                <el-button type="text" size="mini" @click="() => append(data)">
                  新增
                </el-button>
                <el-button
                  type="text"
                  size="mini"
                  @click="() => remove(node, data)"
                >
                  删除
                </el-button>
              </span>
            </span>
          </el-tree>
        </div>
      </el-col>
    </el-row>
    <el-button type="primary" @click="submitForm">确 定</el-button>
  </div>
</template>
        
<script>
let deptId = 10000;
export default {
  name: "TreePage2",
  props: {},
  data() {
    return {
      menuExpand: false,
      menuNodeAll: false,
      menuCheckStrictly: true,
      // 模拟数据
      menuOptions: [
        {
          deptId: 100,
          parentId: 0,
          parentName: null,
          ancestors: "0",
          deptName: "XX01街道",
          children: [
            {
              deptId: 1001,
              parentId: 100,
              parentName: null,
              ancestors: "0,100",
              deptName: "XX1-1村",
              children: [
                {
                  deptId: 10011,
                  parentId: 1001,
                  parentName: null,
                  ancestors: "0,100,1001",
                  deptName: "XX1-1-1村",
                  children: [],
                },
              ],
            },
            {
              deptId: 1002,
              parentId: 100,
              parentName: null,
              ancestors: "0,100",
              deptName: "XX1-2村",
              children: [
                {
                  deptId: 10021,
                  parentId: 1002,
                  parentName: null,
                  ancestors: "0,100,1002",
                  deptName: "XX1-2-1村",
                  children: [],
                  disabled: true, //禁用
                },
              ],
            },
            {
              deptId: 1003,
              parentId: 100,
              parentName: null,
              ancestors: "0,100",
              deptName: "XX1-3村",
              children: [],
            },
          ],
        },
        {
          deptId: 200,
          parentId: 0,
          parentName: null,
          ancestors: "0",
          deptName: "XX02街道",
          children: [
            {
              deptId: 2001,
              parentId: 200,
              parentName: null,
              ancestors: "0,200",
              deptName: "XX2-1村",
              children: [],
            },
            {
              deptId: 2002,
              parentId: 200,
              parentName: null,
              ancestors: "0,200",
              deptName: "XX2-2村",
              children: [],
            },
            {
              deptId: 2003,
              parentId: 200,
              parentName: null,
              ancestors: "0,200",
              deptName: "XX2-3村",
              children: [],
            },
          ],
        },
      ],
      // 村名称
      deptName: undefined,
      defaultProps: {
        children: "children",
        label: "deptName",
      },
      // 默认展开的节点的 key 的数组
      defaultExpandedKeys: [100, 10021],
      // 默认展开的节点的 选中 的数组
      defaultCheckedKeys: [1001],
    };
  },
  watch: {
    // 在需要对节点进行过滤时,调用 Tree 实例的filter方法,参数为关键字。
    // 需要注意的是,此时需要设置filter-node-method,值为过滤函数。
    // 根据名称筛选村社树
    deptName(val) {
      this.$refs.menu.filter(val);
    },
  },
  methods: {
    // 树权限(展开/折叠)
    handleCheckedTreeExpand(value) {
      let treeList = this.menuOptions;
      for (let i = 0; i < treeList.length; i++) {
        this.$refs.menu.store.nodesMap[treeList[i].deptId].expanded = value;
      }
    },
    // 树权限(全选/全不选)
    handleCheckedTreeNodeAll(value) {
      this.$refs.menu.setCheckedNodes(value ? this.menuOptions : []);
    },
    // 树权限(父子联动)
    handleCheckedTreeConnect(value) {
      this.menuCheckStrictly = value ? true : false;
    },
    // 过滤函数
    filterNode(value, data) {
      // console.log(value, data)
      if (!value) return true;
      return data.deptName.indexOf(value) !== -1;
    },
    // 左侧网格树-节点单击事件
    handleNodeClick(data) {
      console.log(data, "左侧网格树-节点单击事件");
    },
    // 所有菜单节点数据
    getMenuAllCheckedKeys() {
      // 目前被选中的菜单节点
      let checkedKeys = this.$refs.menu.getCheckedKeys();
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
      return checkedKeys;
    },
    // 新增节点
    append(data) {
      const newChild = { deptId: deptId++, deptName: "test", children: [] };
      if (!data.children) {
        this.$set(data, "children", []);
      }
      data.children.push(newChild);
    },
    // 删除节点
    remove(node, data) {
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex((d) => d.deptId === data.deptId);
      children.splice(index, 1);
    },

    // 节点开始拖拽时触发的事件
    handleDragStart(node, ev) {
      console.log("drag start", node,ev);
    },
    //   拖拽进入其他节点时触发的事件
    handleDragEnter(draggingNode, dropNode, ev) {
      console.log("tree drag enter: ", dropNode.deptName,ev);
    },
    //   拖拽离开某个节点时触发的事件
    handleDragLeave(draggingNode, dropNode, ev) {
      console.log("tree drag leave: ", dropNode.deptName,ev);
    },
    //   在拖拽节点时触发的事件(类似浏览器的 mouseover 事件)
    handleDragOver(draggingNode, dropNode, ev) {
      console.log("tree drag over: ", dropNode.deptName,ev);
    },
    //   拖拽结束时(可能未成功)触发的事件
    handleDragEnd(draggingNode, dropNode, dropType, ev) {
      console.log("tree drag end: ", dropNode && dropNode.deptName, dropType,ev);
    },
    //   拖拽成功完成时触发的事件
    handleDrop(draggingNode, dropNode, dropType, ev) {
      console.log("tree drop: ", dropNode.deptName, dropType,ev);
    },
    //   拖拽时判定目标节点能否被放置。type 参数有三种情况:'prev'、'inner' 和 'next',
    // 分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
    allowDrop(draggingNode, dropNode, type) {
      if (dropNode.data.deptName === "XX1-1-1村") {
        return type !== "inner";
      } else {
        return true;
      }
    },
    //   判断节点能否被拖拽
    allowDrag(draggingNode) {
      return draggingNode.data.deptName.indexOf("XX1-2-1村") === -1;
    },

    /** 提交按钮 */
    submitForm() {
      let menuIds = this.getMenuAllCheckedKeys();
      console.log(menuIds, "menuIds");
    },
  },
};
</script>
        
      
<style scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
             

2. 效果图

在这里插入图片描述

3. 使用到的部分属性说明

  1. default-expanded-keys: 默认展开的节点的 key 的数组;
  2. expand-on-click-node: 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点;
  3. node-key :每个树节点用来作为唯一标识的属性,整棵树应该是唯一的;
  4. filter-node-method: 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏;
  5. node-click :节点被点击时的回调;
  6. accordion: 是否每次只打开一个同级树节点展开;
  7. default-expand-all: 是否默认展开所有节点 ;
  8. 通过 draggable: 属性可让节点变为可拖拽;

4. 更多属性配置查看element官网

https://element.eleme.cn/#/zh-CN/component/tree

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

非接触式红外测温MLX90614

1.MLX90614简介 MX90614是一款由迈来芯公司提供的低成本&#xff0c;无接触温度计。输出数据和物体温度呈线性比例&#xff0c;具有高精度和高分辨率。TO-39金属封装里同时集成了红外感应热电堆探测器芯片MLX81101&#xff08;温度是通过PTC或是PTAT元件测量&#xff09;和信号…

vue简单实现滚动条

背景&#xff1a;产品提了一个需求在一个详情页&#xff0c;一个form表单元素太多了&#xff0c;需要滚动到最下面才能点击提交按钮&#xff0c;很不方便。他的方案是&#xff0c;加一个滚动条&#xff0c;这样可以直接拉到最下面。 优化&#xff1a;1、支持滚动条&#xff0c;…

uniapp 【专题详解 -- 时间】云数据库时间类型设计,时间生成、时间格式化渲染(uni-dateformat 组件的使用)

云数据表的时间类型设计 推荐使用时间戳 timestamp "createTime": {"bsonType": "timestamp","label": "创建时间&#xff1a;" }时间生成 获取当前时间 Date.now() .add({createTime: Date.now() })时间格式化渲染 下载安…

Prototype原型模式(对象创建)

原型模式&#xff1a;Prototype 链接&#xff1a;原型模式实例代码 注解 模式定义 使用原型实例指定创建对象的种类&#xff0c;然后通过拷贝这些原型来创建新的对象。 ——《设计模式》GoF 目的 在软件系统中&#xff0c;经常面临这“某些结构复杂的对象”的创建工作&am…

Chapter 7 - 10. Congestion Management in Ethernet Storage Networks以太网存储网络的拥塞管理

Detecting Congestion on a Remote Monitoring Platform Remote monitoring platforms can monitor all the ports in a network simultaneously to provide network-wide single-pane-of-glass visibility. 远程监控平台可同时监控网络中的所有端口,以提供全网单一窗口可视性…

selenium 用webdriver.Chrome 访问网页闪退解决方案

1.1.1. 解决方案&#xff1a; 1.1.1.1. 移动插件到谷歌的安装目录下 1.1.1.2. 设置环境变量 1.1.1.3. 重启电脑检查成功 解决时间&#xff1a;5min

Springcloud 微服务实战笔记 Eureka

服务治理 服务注册 在服务治理框架中&#xff0c;通常都会构建一个注册中心&#xff0c;每个服务单元向注册中心登记自己提供的服务&#xff0c;将主机与端口号、版本号、通信协议等一些附加信息告知注册中心&#xff0c;注册中心按服务名分类组织服务清单。当服务启动后&…

STM32学习笔记二十一:WS2812制作像素游戏屏-飞行射击游戏(11)探索游戏脚本

还记得上次在第十七章中为BOSS创建的路径动画吧。我们写了一大坨的代码来描述BOSS的运动路径&#xff0c;但凡是写过几年代码的人都不会干出这样的事情。-_-! 没办法&#xff0c;谁叫那时候还没有脚本呢。这章就来补齐这块短板。 脚本属于配置化的一种&#xff0c;你可以把脚…

MongoDB数据类型详解

BSON 协议与数据类型 MongoDB 为什么会使用 BSON&#xff1f; JSON 是当今非常通用的一种跨语言 Web 数据交互格式&#xff0c;属 ECMAScript 标准规范的一个子集。JSON &#xff08;JavaScript Object Notation&#xff0c;JS 对象简谱&#xff09;即 JavaScript 对象表示法…

Docker网络相关操作

文章目录 网络相关操作1 网络模式1.1 bridge模式1.2 host模式1.3 Container网络模式1.4 none模式1.5 overlay网络模式1.6 macvlan网络模式 2 bridge网络2.1 通过link的方式2.2 新建bridge网络 3 none网络4 host网络5 网络命令汇总5.1 查看网络5.2 创建网络5.3 删除网络5.4 查看…

Python 中的==操作符 和 is关键字

Python是一种功能强大的通用编程语言&#xff0c;提供了各种比较值和对象的方法。其中包括操作符和is关键字&#xff0c;它们的用途不同&#xff0c;但由于它们有时可以达到相同的目的&#xff0c;所以经常会被混淆。在本文中&#xff0c;我们将深入研究和is之间的区别&#xf…

过滤器亚马逊审核UL900报告标准

过滤器亚马逊审核UL900防火等级检测标准,要符合ISO17025资质实验室出具的报告才能成功的上架亚马逊平台。 过滤器&#xff08;filter&#xff09;是输送介质管道上不可缺少的一种装置&#xff0c;通常安装在减压阀、泄压阀、定水位阀 ,方工过滤器其它设备的进口端设备。过滤器…

wsl(ubuntu)创建用户

我们打卡ubuntu窗口&#xff0c;如果没有创建用户&#xff0c;那么默认是root用户 用户的增删改查 查 查询所有的用户列表 cat /etc/passwd | cut -d: -f1cat /etc/passwd: 这个命令用于显示 /etc/passwd 文件的内容。/etc/passwd 文件包含了系统上所有用户的基本信息。每一…

Java字符串:构建和操作字符序列的动态工具

&#x1f451;专栏内容&#xff1a;Java⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、常用方法1、字符串构造2、String对象的比较Ⅰ、比较是否引用同一个对象Ⅱ、 按照字典序比较 3、转换Ⅰ、数值和字符串的转换…

探索 OceanBase 中图数据的实现

在数据管理和处理的现代环境中&#xff0c;对能够处理复杂数据结构的复杂数据模型和方法的需求从未如此迫切。图数据的出现以其自然直观地表示复杂关系的独特能力&#xff0c;开辟了数据分析的新领域。 虽然 Neo4j 等成熟的图形数据库为处理图形数据提供了强大的解决方案&…

HTML 使用 ruby 给汉字加拼音

使用 ruby 给汉字加拼音 兼容性 使用 ruby 给汉字加拼音 大家有没有遇到过要给汉字头顶上加拼音的需求? 如果有的话, 你是怎么解决的呢? 如果费尽心思, 那么你可能走了很多弯路, 因为 HTML 原生就有这样的标签来帮我们实现类似的需求. <ruby> ruby 本身是「红宝石」…

K8S陈述式资源管理(1)

命令行: kubectl命令行工具 优点: 90%以上的场景都可以满足对资源的增&#xff0c;删&#xff0c;查比较方便&#xff0c;对改不是很友好 缺点:命令比较冗长&#xff0c;复杂&#xff0c;难记声明式 声明式&#xff1a;K8S当中的yaml文件来实现资源管理 GUI&#xff1a;图形…

C#,入门教程(08)——基本数据类型及使用的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(07)——软件项目的源文件与目录结构https://blog.csdn.net/beijinghorn/article/details/124139947 数据类型用于指定数据体&#xff08;DataEntity&#xff0c;包括但不限于类或结构体的属性、变量、常量、函数返回值&#xff09;…

3_并发编程可见性(volatile)之缓存锁内存屏障过程

并发编程可见性volatile 1.背景原来 从下面的程序可以知道main线程把stop修改成false&#xff0c;而在t1线程没有中没有读取到stop值为false&#xff0c;所以导致了t1线程不能够停止。 从而说明stop值在线程t1不可见&#xff0c;解决这个问题在stop变量上添加volatile即可(p…

java spring boot 获取resource目录下的文档

主要代码 String filePath"templates/test.xls" ClassPathResource classPathResource new ClassPathResource(filePath); InputStream inputStream classPathResource.getInputStream();目录 主要目录存放再这 代码案例 public void downloadTemplate( HttpS…