vue用递归组件写树形控件的实例代码


Posted in Javascript onJuly 19, 2018

最近在vue项目中遇到需要用树形控件的部分,比如导航目录是不确定的,所以必须要用树形结构,不管导航目录有几级,都可以自动显示出来,我一开始觉得element-ui有树形控件,不需要自己写,调用就可以了,后来才发现,调用完事之后,样式不可控,而且要加东西特别困难,无法满足项目需求,于是,一首《凉凉》送给自己,后来去翻vue官网,发现居然有递归组件,一开始我写了两个组件,互相调用,可以写出来,后来返现,如果项目要用到5棵树,我要写10个组件,而且样式控制起来超级恶心,于是我就各种查资料,原生的也试过了,原生js写的并不能在vue项目中使用,因为它用js创造的元素,违反了vue数据驱动视图的原则,所以pass,又听一遍《凉凉》,当然如果有小伙伴对原生js写的树形结构感兴趣我也可以贴出来,那么我们先来看看vue版的吧,后来,我就一直在默念“递归”这个词,递归不就是自己调自己吗,我可以只写一个组件,来调用自己啊,也许应该可以,后来,经过试验终于成功了,下面我贴上代码

vue版的树形控件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>树形结构2</title>
</head>
<body>
  <div id = "app">
    <tree :folder = "trees" :select = "select"></tree>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    Vue.component('tree', {
      name:"tree",
      template:`<ul>
            <li v-for = "item in folder">
              <span @click = "select(item)">{{ item.label }}</span>
              <tree v-if = "item.children" :folder = "item.children" :select = "select"></tree>
            </li>
          </ul>`,
      props:["folder","select"],
    })
    // <tree v-if = "item.children" :folder = "item.children"></tree>
    var app = new Vue({
      el:"#app",
      data:{
        msg:"hello world",
        trees: [
          {
            id:1,
            label:"1级目录1",
            show:false,
            children:[
              {
                id:"1-1",
                label:"1.1目录"
              },
              {
                id:"1-2",
                label:"1.2目录"
              },
              {
                id:"1-3",
                label:"1.3目录"
              },
            ]
          },
          {
            id:2,
            label:"1级目录2",
            show:false
          },
          {
            id:3,
            label:"1级目录3",
            show:false,
            children:[
              {
                id:"3-1",
                label:"3.1目录"
              },
              {
                id:"3-2",
                label:"3.2目录",
                show:false,
                children:[
                  {
                    id:"3-2-1",
                    label:"3.2.1目录"
                  },
                  {
                    id:"3-2-2",
                    label:"3.2.2目录"
                  },
                  {
                    id:"3-2-3",
                    label:"3.2.3目录"
                  }
                ]
              }
            ]
          },
          {
            id:4,
            label:"1级目录4",
            show:false,
            children:[
              {
                id:"4-1",
                label:"4.1目录"
              },
              {
                id:"4-2",
                label:"4.2目录",
                show:false,
                children:[
                  {
                    id:"4-2-1",
                    label:"4.2.1目录"
                  }
                ]
              }
            ]
          },
          {
            id:5,
            label:"1级目录5",
            show:false,
            children:[
              {
                id:"5-1",
                label:"5.1目录",
                show:false,
                children:[
                  {
                    id:"5-1-1",
                    label:"5.1.1目录"
                  },
                  {
                    id:"5-1-2",
                    label:"5.1.2目录",
                    show:false,
                    children:[
                      {
                        id:"5-1-2-1",
                        label:"5.1.2.1目录"
                      },
                    ]
                  }
                ]
              },
              {
                id:"5-2",
                label:"5.2目录",
                show:false
              }
            ]
          },
        ]
      },
      methods:{
        clickHandler(){
          console.log(23333);
        },
        select(data){
          console.log(data);
        }
      },
      mounted(){
        console.log(this.trees);
      }
    })
  </script>
</body>
</html>

看下结果

vue用递归组件写树形控件的实例代码

当然我用的全局组件,如果用vue-cli搭建的环境是一样的,引入组件就可以了,但是一定要注意,组件内必须要用name属性,而且name的名称要和组件名称(组件标签名称)一致才可以

贴一个项目中用的模板吧,相当于做笔记了

<template>
  <ul class = "dataBaseTree">
    <li v-for = "(item,index) in folder" :key = "index">
      <span @click = "select(item)" :class = "{'active':currentId == item.id}">
        <i class = "folderIcon" v-if = "item.children">
          <icon :icon = "'xiala'" v-if = "item.show"></icon>
          <icon :icon = "'xiala2'" v-else></icon>
        </i>
        {{ item.label }}
      </span>
      <el-collapse-transition>
        <DatabaseTree v-if = "item.children && item.show" :folder = "item.children" :select = "select" :currentId = "currentId"></DatabaseTree>
      </el-collapse-transition>
    </li>
  </ul>
</template>

<script>
  import { mapGetters , mapActions} from 'vuex';
  export default{
    name:"DatabaseTree",
    props:["folder","select","currentId"],
    data(){
      return{
        addParams:{
          label:"",
          children:[]
        },
        noteData:{
          children:[]
        }
      }
    },
     computed:{
      ...mapGetters(["catalog"])
    },
    methods:{}
  }
</script>

<style lang="scss" scoped>
  .dataBaseTree{
    padding-left:12%;
    line-height:40px;
    ul{
      padding-left:12%;
      line-height:40px;
      li{
        span{
          display:inline-block;
          padding-left:23%;
          height:100%;
          width:120%;
          color:#ababab;
          font-size:14px;
          position: relative;
          cursor: pointer;
          &:hover{
            background: #EDF0F5;
          }
          .folderIcon{
            color:#BCBCBC;
            position: absolute;
            top:-1px;
            left:22px;
          }
        }
      }
    }
    li{
      position: relative;
      span{
        display:inline-block;
        padding-left:40px;
        font-size:14px;
        height:100%;
        width:120%;
        cursor: pointer;
        position: relative;
        right:25px;
        top:-2px;
        color:#ababab;
        &:hover{
          background: #EDF0F5;
        }
        .titleIcon{
          color:#C3C3C3;
          font-size:16px;
          position: absolute;
          top:12px;
          left:16px;
        }
        .folderIcon{
          color:#BCBCBC;
          position: absolute;
          top:-1px;
          left:22px;
        }
      }
      .active{
        background: #EDF0F5;
      }
    }
  }
</style>

vue版的就到这里了

 下面贴一个原生js版的,感兴趣的小伙伴可以继续往下看

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    var tree=[
        {
          id:1,
          label:"1级目录1",
          children:[
            {
              id:"1-1",
              label:"1.1目录"
            },
            {
              id:"1-2",
              label:"1.2目录"
            },
            {
              id:"1-3",
              label:"1.3目录"
            },
          ]
        },
        {
          id:2,
          label:"1级目录2",
        },
        {
          id:3,
          label:"1级目录3",
          children:[
            {
              id:"3-1",
              label:"3.1目录"
            },
            {
              id:"3-2",
              label:"3.2目录",
              children:[
                {
                  id:"3-2-1",
                  label:"3.2.1目录"
                },
                {
                  id:"3-2-2",
                  label:"3.2.2目录"
                },
                {
                  id:"3-2-3",
                  label:"3.2.3目录"
                }
              ]
            }
          ]
        },
        {
          id:4,
          label:"1级目录4",
          children:[
            {
              id:"4-1",
              label:"4.1目录"
            },
            {
              id:"4-2",
              label:"4.2目录",
              children:[
                {
                  id:"4-2-1",
                  label:"4.2.1目录"
                }
              ]
            }
          ]
        },
        {
          id:5,
          label:"1级目录5",
          children:[
            {
              id:"5-1",
              label:"5.1目录",
              children:[
                {
                  id:"5-1-1",
                  label:"5.1.1目录"
                },
                {
                  id:"5-1-2",
                  label:"5.1.2目录",

                  children:[
                    {
                      id:"5-1-2-1",
                      label:"5.1.2.1目录"
                    },
                  ]
                }
              ]
            },
            {
              id:"5-2",
              label:"5.2目录"
            }
          ]
        },
      ];
    var render = function(tree) {
      if (!tree) return null
      var ul = document.createElement('ul');
      for(var i = 0; i < tree.length;i++){
        var li = document.createElement('li')
        // 创建span标签
        var span = document.createElement('span'); span.innerText = tree[i].label;
        li.appendChild(span);
        if(tree[i].children){
          var sub = render(tree[i].children);
          li.appendChild(sub);
        }
        ul.appendChild(li);
      }
      return ul
    };
    document.body.innerHTML = '';
    document.body.appendChild(render(tree)); 
  </script>
</body>
</html>

看下结果

vue用递归组件写树形控件的实例代码

总结

以上所述是小编给大家介绍的vue用递归组件写树形控件的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript 实现父窗口引用弹出窗口的值的脚本
Aug 07 Javascript
如何确保JavaScript的执行顺序 之jQuery.html深度分析
Mar 03 Javascript
JavaScript中数组的排序、乱序和搜索实现代码
Nov 30 Javascript
js实现绿白相间竖向网页百叶窗动画切换效果
Mar 02 Javascript
vue的props实现子组件随父组件一起变化
Oct 27 Javascript
那些精彩的JavaScript代码片段
Jan 12 Javascript
Node调用Java的示例代码
Sep 20 Javascript
详解关于Vue版本不匹配问题(Vue packages version mismatch)
Sep 17 Javascript
详解React服务端渲染从入门到精通
Mar 28 Javascript
微信小程序实现的五星评价功能示例
Apr 25 Javascript
Koa从零搭建到Api实现项目的搭建方法
Jul 30 Javascript
vue 兄弟组件的信息传递的方法实例详解
Aug 30 Javascript
如何理解Vue的v-model指令的使用方法
Jul 19 #Javascript
JavaScript去掉数组重复项的方法分析【测试可用】
Jul 19 #Javascript
微信小程序自定义对话框弹出和隐藏动画
Jul 19 #Javascript
浅谈Vue初学之props的驼峰命名
Jul 19 #Javascript
解决vue-cli3 使用子目录部署问题
Jul 19 #Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
Jul 19 #Javascript
微信小程序实现分享到朋友圈功能
Jul 19 #Javascript
You might like
定制404错误页面,并发信给管理员的程序
2006/10/09 PHP
PHP处理大量表单字段的便捷方法
2015/02/07 PHP
php 自定义错误日志实例详解
2016/11/12 PHP
php运行报错Call to undefined function curl_init()的最新解决方法
2016/11/20 PHP
Javascript select下拉框操作常用方法
2009/11/09 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
JS实现方向键切换输入框焦点的方法
2015/08/19 Javascript
js变形金刚文字特效代码分享
2015/08/20 Javascript
js调出上下文菜单的实例
2015/12/17 Javascript
【经典源码收藏】jQuery实用代码片段(筛选,搜索,样式,清除默认值,多选等)
2016/06/07 Javascript
探索webpack模块及webpack3新特性
2017/09/18 Javascript
原生JS实现小小的音乐播放器
2017/10/16 Javascript
zepto.js 实时监听输入框的方法
2018/12/04 Javascript
Vue自定义指令上报Google Analytics事件统计的方法
2019/02/25 Javascript
原生JavaScript实现拖动校验功能
2020/09/29 Javascript
[01:28:24]NAVI vs VG Supermajor 败者组 BO3 第三场 6.5
2018/06/06 DOTA
[03:02]安得倚天剑,跨海斩长鲸——中国军团出征DOTA2国际邀请赛
2018/08/14 DOTA
下载糗事百科的内容_python版
2008/12/07 Python
python实现ftp客户端示例分享
2014/02/17 Python
详解在Python和IPython中使用Docker
2015/04/28 Python
举例讲解Python中的死锁、可重入锁和互斥锁
2015/11/05 Python
Python实现的基数排序算法原理与用法实例分析
2017/11/23 Python
简单了解Django模板的使用
2017/12/20 Python
Python实现k-means算法
2018/02/23 Python
python学习基础之循环import及import过程
2018/04/22 Python
PyQt5 QTableView设置某一列不可编辑的方法
2019/06/25 Python
Python3 批量扫描端口的例子
2019/07/25 Python
python实现超级玛丽游戏
2020/03/18 Python
python 使用递归的方式实现语义图片分割功能
2020/07/16 Python
python 6种方法实现单例模式
2020/12/15 Python
html5移动端自适应布局的实现
2020/04/15 HTML / CSS
微软美国官方网站:Microsoft美国
2018/05/10 全球购物
大整数数相乘的问题
2012/07/22 面试题
军训自我鉴定范文
2014/02/13 职场文书
大学生评语大全
2014/04/18 职场文书
Python中使用ipython的详细教程
2021/06/22 Python