高级组件封装技巧--tree的封装

news2024/9/22 23:32:29

el-tree是一个经常用到的组件,但是它不支持v-model,使用起来很麻烦,这篇教程封装了el-tree,使得它使用起来很简单,并且支持搜索,支持叶子节点横向排列,这样就算数据多了,也会显的很紧凑,同时它支持提交halfCheck节点,这点在做菜单管理的时候很有用,如果数据中不保存halfCheck,你需要向上遍历父节点,但是保存了父节点在回显的时候会有问题,因为只要父节点选中子节点都会选中,这些在组件封装中都做了处理

组件的封装 

<template>
  <div>
    <el-input v-model="filterText" placeholder="请输入搜索条件" v-if="filter" clearable/>
    <el-tree v-bind="allProps" ref="treeRef" :filter-node-method="filterNode"
             @check="handleCheck"/>
  </div>
</template>

<script lang="ts">
// @ts-nocheck
export default {
  name: "ui-tree",
  props: { // 参考 https://element-plus.org/zh-CN/component/tree.html#%E5%B1%9E%E6%80%A7
    modelValue: {default: () => []}, //要提交的表单值
    nodeKey: {default: 'id'}, //每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
    defaultExpandAll: {default: true}, //是否默认展开所有节点
    showCheckbox: {default: true}, //是否显示选择框
    data: {default: null}, //树的数据
    filter: {default: true}, //是否显示过滤框
    leafInline: {default: true}, //叶子节点是否显示成一行
    props: { //参考:https://element-plus.org/zh-CN/component/tree.html#props
      type: Object, default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      textValue: '', //view模式显示的内容
      userChecked: false, //是否用户引起的变化
      filterText: '',
      allProps: {
        ...this.$attrs,
        ...this.$props
      }
    }
  },
  created() {
    if (this.leafInline) {
      this.props.class = this.customNodeClass
    }
  },
  mounted() {
    this.setChecked()
  },
  watch: {
    'modelValue': {
      handler(val) {
        this.setChecked()
      },
    },
    // 过滤
    filterText(val) {
      this.$refs.treeRef.filter(val)
    },
  },
  computed: {
    labelField() {
      if (!this.props || !this.props.label) return 'label'
      return this.props.label
    },
    childrenField() {
      if (!this.props || !this.props.children) return 'children'
      return this.props.children
    },
  },
  methods: {
    // 设置选中的节点
    setChecked() {
      let val = this.modelValue
      //如果是用户点击则不设置
      if (this.userChecked) {
        this.userChecked = false
        return
      }
      if (!val || !this.$refs.treeRef) return
      let leafNode = []
      // 如果后台保存了half节点,需要过滤掉
      this.filterLeafNode(leafNode, this.data, val)
      this.$refs.treeRef.setCheckedKeys(leafNode)
    },
    //用户选择后回调
    handleCheck(data, check) {
      this.updateModelValue(check.halfCheckedKeys, check.checkedKeys)
    },
    updateModelValue(halfCheckedKeys, checkedKeys) {
      this.userChecked = true
      let checkIds = []
      checkIds.push(...halfCheckedKeys)
      checkIds.push(...checkedKeys)
      this.$emit('update:modelValue', checkIds)
    },
    //根据搜索框过滤节点
    filterNode(value: string, data) {
      // 该方法会遍历所有节点,显示返回为true的节点
      if (!value) return true
      return data[this.labelField].includes(value)
    },
    // 过滤父节点,只返回叶子节点
    filterLeafNode(leafNode, children, checkedArray) {
      if (!children) return []
      children.forEach(item => {
        if (!item[this.childrenField] || item[this.childrenField].length == 0) {
          if (checkedArray.indexOf(item[this.nodeKey]) > -1) {
            leafNode.push(item[this.nodeKey])
          }
        } else {
          this.filterLeafNode(leafNode, item[this.childrenField], checkedArray)
        }
      })
    },
    customNodeClass(data, node) {
      if (node.isLeaf) return ''
      let addClass = true
      for (const key in node.childNodes) {
        if (!node.childNodes[key].isLeaf) {
          addClass = false
        }
      }
      let levelClass = 'level-' + node.level
      return addClass ? `penultimate-node ${levelClass}` : ''
    },
  }
}
</script>

<style>
.penultimate-node .el-tree-node__children {
  line-height: 12px;
}

.el-tree-node.penultimate-node > .el-tree-node__children {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.el-tree-node.penultimate-node.level-1 > .el-tree-node__children {
  padding-left: 30px;
}
.el-tree-node.penultimate-node.level-2 > .el-tree-node__children {
  padding-left: 48px;
}
.el-tree-node.penultimate-node.level-3 > .el-tree-node__children {
  padding-left: 64px;
}
.el-tree-node.penultimate-node.level-4 > .el-tree-node__children {
  padding-left: 84px;
}

.penultimate-node .el-tree-node__children > .el-tree-node .el-tree-node__content {
  padding-left: 12px !important;
}

.penultimate-node .el-tree-node__children .el-tree-node__content .el-tree-node__expand-icon {
  display: none;
}
</style>

组件的使用

node-key就是绑定值,如果要form绑定id就传id,组件默认显示label,子节点保存在children里面,如果要变更可以通过:props="{label:'title',children:'children'}"来实现

<template>
  <div style="width: 400px">
    <ui-tree :data="data" node-key="label" v-model="form"></ui-tree>
  </div>
</template>

<script>
import UiTree from "@/components/ui-tree.vue";
export default {
  name: "tree",
  components: {UiTree},
  data() {
    return {
      form: ['菜单管理'],
      data: [{label: '系统管理',children:[{label:'用户管理', children:[{label:'菜单管理'},{label:'按钮管理'},{label:'权限管理'}]},{label:'角色管理'}]},
        {label:'文档管理',children:[{label:'目录管理'},{label:'图片管理'},{label:'文件管理'}]}]
    }
  },
}
</script>

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

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

相关文章

springboot+mybatis+vue2分页功能开发

前端框架代码 <div class"block"><span class"demonstration">完整功能</span><el-paginationsize-change"handleSizeChange"current-change"handleCurrentChange":current-page"currentPage4":page-s…

MLM:多模态大型语言模型的简介、微调方法、发展历史及其代表性模型、案例应用之详细攻略

MLM&#xff1a;多模态大型语言模型的简介、微调方法、发展历史及其代表性模型、案例应用之详细攻略 目录 相关文章 AI之MLM&#xff1a;《MM-LLMs: Recent Advances in MultiModal Large Language Models多模态大语言模型的最新进展》翻译与解读 MLM之CLIP&#xff1a;CLIP…

Draw.io for Mac/Win:免费且强大的流程图绘制工具

在数字化时代&#xff0c;流程图已成为表达复杂过程和逻辑关系的重要工具。Draw.io&#xff08;现也称为diagrams.net&#xff09;&#xff0c;作为一款免费且功能强大的流程图绘制工具&#xff0c;无论是对于Mac还是Windows用户&#xff0c;都是不可多得的选择。 一、跨平台兼…

计算机毕业设计 半成品配菜平台 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

智能电网中巡检机器人的信息安全技术应用

随着电力行业的数字化和智能化发展&#xff0c;智能巡检机器人作为电力系统自动化运维的重要工具&#xff0c;能够在无人干预的情况下&#xff0c;对电网设备进行实时监测和故障诊断。这种高效、可靠的巡检方式在智能电网建设中发挥了重要作用。然而&#xff0c;随着机器人在电…

yolo 3d车辆目标检测(教程+代码)

关于3D目标检测及其与YOLO3D相关性的概览&#xff1a; 3D目标检测&#xff1a;开启视觉感知的新维度 随着计算机视觉技术的发展&#xff0c;目标检测算法已经成为人工智能领域的重要组成部分。从自动驾驶汽车到无人机导航&#xff0c;再到增强现实&#xff08;AR&#xff09;应…

Java项目:137 springboot基于springboot的智能家居系统

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本基于Springboot的智能家居系统提供管理员、用户两种角色的服务。 总的功能个人中心、基础数据管理、家具管理、任务管理和用户管理。本系统…

计算机工具软件安装攻略:Visual Studio Code下载、安装和使用

Visual Studio Code下载、安装和使用 1 Visual Studio Code简介 Visual Studio Code通常简称为VS Code&#xff0c;是一款由微软开发的免费、开源的轻量级代码编辑器。它在开发者社区中非常受欢迎&#xff0c;具有强大的功能和扩展性&#xff0c;适用于多种编程语言和开发场景…

git如何设置嵌套仓库(设置子树或子模块),并解决直接将一个仓库拖拽到另一个仓库中导致的问题

git 将一个仓库拷贝到另一个仓库的文件夹下。默认git并不会处理&#xff0c;上传上去之后&#xff0c;只会创建一个文件夹&#xff0c;但是这个文件夹点不开。 在 git add . 的时候&#xff0c;会报出警告&#xff1a; 警告&#xff1a;正在添加嵌入式 git 仓库&#xff1a;cl…

微链接: 利用 MinIO 实现计算和存储的还原

Microblink 是一家专门从事图像检测的 AI 公司。他们从 BlinkID、BlinkID Verify 和 BlinkCard 等产品开始进入身份空间。最近&#xff0c;他们的图像检测能力催生了可以处理其他类型图像的产品。例如&#xff0c;可以对收据执行产品检测&#xff0c;从而使用收据上的产品描述来…

Update Azure OpenAI npm Package to 2023-12-01-preview Version

题意&#xff1a;将 Azure OpenAI npm 包更新到 2023-12-01-preview 版本 问题背景&#xff1a; I am currently using the azure-openai npm package in my project with version 2023-03-15-preview. As per the latest updates, version 2023-12-01-preview is available a…

【论文分享】MyTEE: Own the Trusted Execution Environment on Embedded Devices 23‘NDSS

目录 AbstractINTRODUCTIONBACKGROUNDARMv8 ArchitectureSecurity statesTrustZone extensionsVirtualization Communication with Peripherals MOTIVATIONATTACK MODEL AND ASSUMPTIONSYSTEM DESIGNOverviewExecution Environments IsolationDMA FilterExternal DMA controlle…

负载均衡--资源申请说明(三)

1.负载方式&#xff1a;分为四层负载和七层负载 2.负载协议&#xff1a;四层负载为TCP和UDP&#xff0c;七层负载为HTTP和HTTPS 4.负载端口&#xff1a;填写虚地址的端口&#xff08;一般与后端服务端口保持一致&#xff09; 5.真实服务IP&#xff1a;指被负载的后台真实服务…

零售自动化新趋势:AI 智能名片与 S2B2C 商城系统助力零售业变革

摘要&#xff1a;本文深入探讨零售业所面临的多重压力&#xff0c;分析客户期望不断提高的现状&#xff0c;强调零售商追求自动化的必要性。引入零售自动化的概念&#xff0c;阐述其通过技术实现零售体验自动化或半自动化&#xff0c;提供线上线下无缝连接、快速和个性化体验的…

MATLAB实现跳频多频移键控通信系统仿真

1. 简介 在现代无线通信系统中&#xff0c;跳频技术和多频移键控&#xff08;MFSK&#xff09;调制被广泛应用于抗干扰和提高通信系统性能。本文将通过 MATLAB 仿真分析跳频 MFSK 通信系统的性能&#xff0c;特别是在不同信道干扰条件下的误码率&#xff08;BER&#xff09;表…

ultralytics框架实现ByteTrack目标追踪算法

在ultralytics框架中&#xff0c;提供了两种用于目标追踪的算法&#xff0c;分别是ByteTrack算法与Botsort算法&#xff0c;这两种算法都是在Sort算法的基础上改进的&#xff0c;今天&#xff0c;我们学习一下ByteTrack算法。 存在问题 首先&#xff0c;我们看下ByteTrack所解…

《数字信号处理》学习04-离散时间系统中的线性时不变系统

目录 一&#xff0c;系统及离散时间系统 二&#xff0c;离散时间系统中的线性时不变系统 1&#xff0c;线性系统 1) 可加性 2) 比例性(齐次性) 3&#xff09;叠加原理(叠加性质) 2&#xff0c;时不变系统(移不变系统) 通过前几篇文章的学习&#xff0c;此时我对序列的相关概…

毒枸杞事件启示录:EasyCVR视频AI智能监管方案如何重塑食品卫生安全防线

一、方案背景 近年来&#xff0c;食品安全问题频发&#xff0c;引发了社会各界的广泛关注。其中&#xff0c;毒枸杞事件尤为引人关注。新闻报道&#xff0c;在青海格尔木、甘肃靖远等地&#xff0c;部分商户为了提升枸杞的品相&#xff0c;违规使用焦亚硫酸钠和工业硫磺进行“…

深度学习5从0到1理解RNN(包括LTSM,GRU等):内容丰富(下)

续 5.4.4 LSTM 举例 网络里面只有一个 LSTM 的单元&#xff0c;输入都是三维的向量&#xff0c;输出都是一维的输出。这三维的向量跟输出还有记忆元的关系是这样的。假设 x2 的值是 1 时&#xff0c; x1 的值就会被写到记忆元里&#xff1b;假设 x2 的值是-1 时&#xff0c;就…

时序数据库 IoTDB 为什么选择 TPCx-IoT 基准测评?

IoTDB 在 TPCx-IoT 榜单的 What 与 Why 解答&#xff01; 去年&#xff0c;我们发布了 IoTDB 多项性能表现位居国际数据库性能测试排行榜 benchANT&#xff08;Time Series: DevOps&#xff09;第一名的好消息。 刚刚落幕的数据库顶级会议 VLDB 上&#xff0c;我们又收获了一则…