思考了两天时间,准备仿照ant-design-vue实现一个基于vue的树形控件。主要用到了vue递归组件思想、input的CheckBox类型输入框的使用。

需求

  • 能够将传入的Json数据生成树形目录。
  • 能够初始化选中节点。
  • 能够手动选中节点,最终可将所有选中节点打印出来。
  • 能够在初始化禁用节点。
  • 能够折叠树形目录。
  • 修改原生CheckBox样式。

实例截图

做好的树形控件如下所示,点击获取选中节点key将弹出所有选中的节点:

手把手实现

了解Vue递归组件

在vue的文档(https://cn.vuejs.org/v2/guide/components-edge-cases.html#%E9%80%92%E5%BD%92%E7%BB%84%E4%BB%B6)中说明组件是可以在它们自己的模板中调用自身的。但是他需要两个条件:

  • 组件有name属性
  • 递归调用需要有条件

根据以上说明创建了基础树形控件tree.vue:

全局变量:global.js

在写组件获取节点内容是发现由于是递归组件,并不好拿到每级选中的节点。因此在这里创建global.js全局变量记录所有选中节点。也便于删除和加入节点。
默认选中的节点如下:

const nodes = ['1', '1-1', '1-1-2', '1-2-2']export default {nodes
}

写好后需要在main.js上挂载。

import global from 'common/js/global'
Vue.prototype.$global = global

基础组件(递归组件):tree.vue

说明:这里不需要再用components属性去声明自己了,有了name属性后直接在template中就可以调用名为name值的组件。

<template><ul class="ul-wrapper">                                    <!-- 包裹层--><li v-for="item in list" :key="item.key">                <!-- 遍历--><div>                                                  <!-- 是否展开图标--><img class="icon"v-show="item.children"@click="changeShow":src="require(`../common/images/${imgUrl}`)">                                                  <!-- CheckBox--><inputtype="checkbox":name="item.key"@click="clickbox":checked="isChecked(item.key)":disabled="item.disabled"><div class="checkbox-title">{{item.title}}</div>      <!-- CheckBox内容--></div><tree v-if="showChildren" :list="item.children"></tree> <!-- 遍历children--></li></ul>
</template><script type='text/ecmascript-6'>
export default {name: 'tree',props: {list: { // 所有树节点type: Array,default: () => {return []}}},data () {return {showChildren: true // 是否展开根目录}},computed: { // computed属性计算展开图标imgUrl () {return this.showChildren ? 'down.png' : 'right.png'}},methods: {clickbox (e) { // 点击CheckBox时需要加入或删除已选中this.$global.nodes的节点数组中const checked = e.target.checkedconst key = e.target.nameconst nodes = this.$global.nodes // this.$global.nodes是全局变量,便于递归组件记录选中节点if (checked) {if (!nodes.includes(key)) {this.$global.nodes.push(key)}} else {this.$global.nodes = nodes.filter((item) => {return key !== item})}},changeShow () { // 点击是否展开根目录,当前状态取反即可this.showChildren = !this.showChildren},isChecked (key) { // 查看是否已经存在于选中节点中return this.$global.nodes.includes(key)}}
}
</script><style lang="stylus">
.ul-wrapper                            // ul包裹层,每层需要向右偏移30pxmargin 10px 30px 0.checkbox-title, .icondisplay inline-blockvertical-align middle.iconmargin-left -20pxheight 18pxwidth 18pxinput[type="checkbox"]                  // CheckBox样式修改position relativedisplay inline-blockvertical-align middlepadding 0margin-right 5pxheight 18pxwidth 18pxborder 1px solid #cccborder-radius 3px
input[type="checkbox"]:checked::before // CheckBox选中状态时样式修改position absolutetop 0left 0padding-left 2pxcontent: "\2713";height 15pxwidth 13pxfont-size 12pxfont-weight: bold;background #1296dbcolor #fffborder-radius 3pxborder 0
input[type="checkbox"]:disabled::before // CheckBox禁用状态时样式修改position absolutetop 0left 0padding-left 2pxcontent: "";height 15pxwidth 13pxfont-size 12pxfont-weight: bold;background #ccccolor #fffborder-radius 3pxborder 0
</style>

应用组件 tree-apply.vue

<template><div class="tree-wrapper"><div class="btn" @click="showNodes">点击获取选中节点key</div><Tree :list="treeData"></Tree></div>
</template><script type='text/ecmascript-6'>
import Tree from 'base/tree'
export default {data () {return {treeData: []  // 全部节点}},created () {this.getData()},methods: {getData () {this.axios.get('/tree').then((res) => { // 获取mock数据this.treeData = res.data})},showNodes () {alert(this.$global.nodes)}},components: {Tree}
}
</script><style lang="stylus">
.btnmargin 20pxtext-align center
</style>

mock数据tree.json

这里采用了模拟数据的方法,mock的具体使用方法在我上一篇写的《better-scroll实现轮播图组件》中有提到:https://blog.csdn.net/qq_39083496/article/details/104259280

  • 是否禁用CheckBox是根据 “disabled”: “true”,决定的。
  • title(必须)是显示的label名。
  • key(必须)才是真正的关键字,理解为最后提交时的必要字段。
[{"title": "1","key": "1","children": [{"title": "1-1","key": "1-1","children": [{ "title": "1-1-1", "key": "1-1-1" },{ "title": "1-1-2", "key": "1-1-2" },{ "title": "1-1-3", "key": "1-1-3" }]}, {"title": "1-2","key": "1-2","children": [{ "title": "1-2-1", "key": "1-2-1" },{ "title": "1-2-2", "key": "1-2-2" },{ "title": "1-2-3", "key": "1-2-3" }]}, {"title": "1-3","key": "1-3"}]}, {"title": "2","key": "2","disabled": "true","children": [{ "title": "2-1", "key": "2-1" },{ "title": "2-2", "key": "2-2" },{ "title": "2-3", "key": "2-3" }]}, {"title": "3","key": "3"}]

接口:

const Mock = require('mockjs')Mock.mock('/tree', 'get', require('./json/tree.json'))

总结

到此就完成了树形控件的生成,需求部分都已经满足。如果通过以上代码片段不能明白的话,可以在我的github上找到源码。欢迎来访,欢迎Star~
https://github.com/Gesj-yean/vue-demo-collection

理解Vue递归组件,实现Tree树形控件实例~相关推荐

  1. vue树形结构html,怎么在vue中利用递归组件实现一个树形控件

    怎么在vue中利用递归组件实现一个树形控件 发布时间:2021-06-11 17:26:48 来源:亿速云 阅读:81 作者:Leah 本篇文章为大家展示了怎么在vue中利用递归组件实现一个树形控件, ...

  2. vue 树形控件可编辑_vue.js element-ui组件改iview 第一期 tree树形控件

    此为第一期修改,后期也适配了其他组件,更多查看我得文章 element-ui组件的tree树形控件修改源码改为iview组件 实现原理 修改了element-ui源码,把源码里面的tree模块提取出来 ...

  3. elementui tree获取父节点_vue_elementUI_ tree树形控件 获取选中的父节点ID

    一,  vue_elementUI_ tree树形控件 1.1默认点击tree节点的第一个(注意不是checked选中) :expand-on-click-node="false" ...

  4. vue+element tree(树形控件数据格式)组件(1)

    vue+element tree(树形控件数据格式)组件(1), 最近做了第一个组内可以使用的组件,虽然是最简版,也废了不少力.各位前辈帮我解决问题,才勉强搞定.让我来记录这个树形组件的编写过程和期间 ...

  5. React 组件封装之 Tree 树形控件

    React 组件封装之 Tree 树形控件 一.Tree 树形结构 二.使用案例 三.API 使用指南 四.源代码 五.总结 一.Tree 树形结构 组件说明: 实现树形控件,适用于组织架构.文章列表 ...

  6. vue+element-ui之tree树形控件有关子节点和父节点之间的各种选中关系详解

    做后端管理系统,永远是最蛋疼.最复杂也最欠揍的事情,也永远是前端开发人员最苦逼.最无奈也最尿性的时刻.蛋疼的是需求变幻无穷,如同二师兄的三十六般变化:复杂的是开发难度寸步难行,如同蜀道难,难于上青天: ...

  7. Element ui tree树形控件获取当前节点id和父节点id

    低版本Element ui tree树形控件获取当前节点id和父节点id的方法:点击查看 最新版本Element ui tree树形控件获取当前节点id和父节点id教程: 1.找到node_modul ...

  8. 《实用VC编程之玩转控件》第15课:Tree树形控件

    本文转载自:VC驿站 https://www.cctry.com/thread-297465-1-1.html 1.控件简介: Tree树形控件也是我们编程过程中比较常用的一个控件,而且在其他软件中也 ...

  9. Element Tree 树形控件自定义显示样式与hover事件绑定实现添加、删除和修改

    Element Tree 树形控件自定义显示样式与hover事件绑定实现添加.删除和修改 最近在搞erp项目对应后台的管理功能,为了加速开发使用了 vue-element-admin 开发,使用的是e ...

最新文章

  1. Spring boot 整合 Mybatis 实现增删改查(MyEclipse版)
  2. Dell R720上的系统安装问题的解决办法(关于RAID建立磁盘阵列的技术)
  3. 错误请联系管理员文件 index.php,ThinkPHP5框架在写项目过程中遇到的相关问题,以及前端问题-Go语言中文社区...
  4. php弱类型漏洞,php代码审计之弱类型引发的灾难
  5. springboot集成swagger2,构建优雅的Restful API
  6. HashMap,Hashtabel,ConcurrentHashMap的区别
  7. 判断当前环境在微信下,还是企业微信下
  8. java的dtd文件_Eclipse中在XML中如何关联.dtd文件
  9. c语言求最大质数,【C语言】求解素数(质数)的N种境界
  10. Landsat7大气校正后图像变色
  11. 第二个项目前预演,完成了,(第6200小时的时候)
  12. 判断某个字符串是否为数字
  13. 数据库基础(常见面试题)
  14. 立场开源 | 电动锡膏挤出器
  15. 解决连接 ssh 的时候 ,报 The server key has changed 错误
  16. 小白需要知道的git命令
  17. HarmonyOS 能否成为世界第三大操作系统?
  18. Vulkan学习(七): Swap Chain Recreation
  19. 【MySQL】MySQL统计连续登录3天的用户
  20. Android手机数据读写方法(内部存储、SD卡,网络加载,包内文件读取)

热门文章

  1. [主板] [教程]在Windows 2012 R2上安装Intel I217-V/I218-V网卡驱动
  2. Saliency as Evidence: Event Detection with Trigger Saliency Attribution(ACL2022)
  3. 二分图的最大匹配:匈牙利算法,先到先得,能让则让,男生找妹子
  4. 古月居_ROS核心概念
  5. 视频教程-ZStack 带你0基础搭建私有云平台|ZCCT实战培训视频|-云平台
  6. Java图片识别技术
  7. 91手机助手评测:通吃机器人和苹果
  8. html d标签,HTML 标签和属性 - osc_3zu23d0r的个人空间 - OSCHINA - 中文开源技术交流社区...
  9. python 重新执行本次循环_python重新循环
  10. python爱因斯坦阶梯编程_零基础入门学习Python习题1【爱因斯坦台阶+猜数字】