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 相关文章推荐
jquery text()要注意啦
Oct 30 Javascript
推荐40个非常优秀的jQuery插件和教程【系列三】
Nov 09 Javascript
基于jquery的代码显示区域自动拉长效果
Dec 07 Javascript
setinterval()与clearInterval()JS函数的调用方法
Jan 21 Javascript
深入理解JavaScript程序中内存泄漏
Mar 17 Javascript
jQuery简单实现提交数据出现loading进度条的方法
Mar 29 Javascript
js使用Replace结合正则替换重复出现的字符串功能示例
Dec 27 Javascript
Vue 使用中的小技巧
Apr 26 Javascript
element-ui 中使用upload多文件上传只请求一次接口
Jul 19 Javascript
JavaScript计算出两个数的差值
Mar 19 Javascript
vue实现移动端返回顶部
Oct 12 Javascript
Typescript类型系统FLOW静态检查基本规范
May 25 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
用Apache反向代理设置对外的WWW和文件服务器
2006/10/09 PHP
一篇不错的PHP基础学习笔记
2007/03/18 PHP
php fsockopen解决办法 php实现多线程
2014/01/20 PHP
详解PHP中的状态模式编程
2015/08/11 PHP
php利用smtp类实现电子邮件发送
2015/10/30 PHP
简单解决微信文章图片防盗链问题
2016/12/17 PHP
php使用GD2绘制几何图形示例
2017/02/15 PHP
PHP中十六进制颜色与RGB颜色值互转的方法
2019/03/18 PHP
js模拟弹出效果代码修正版
2008/08/07 Javascript
jQuery 加上最后自己的验证
2009/11/04 Javascript
js点击更换背景颜色或图片的实例代码
2013/06/25 Javascript
jQuery大于号(&gt;)选择器的作用解释
2015/01/13 Javascript
JS实现超简单的仿QQ折叠菜单效果
2015/09/21 Javascript
浅谈Nodejs中的作用域问题
2016/12/26 NodeJs
解析Vue.js中的组件
2018/02/02 Javascript
使用vue中的v-for遍历二维数组的方法
2018/03/07 Javascript
vue实现动态添加数据滚动条自动滚动到底部的示例代码
2018/07/06 Javascript
Vue开发之封装上传文件组件与用法示例
2019/04/25 Javascript
JavaScript实现单图片上传并预览功能
2019/09/30 Javascript
python基础教程之基本内置数据类型介绍
2014/02/20 Python
python中enumerate函数用法实例分析
2015/05/20 Python
Python遍历某目录下的所有文件夹与文件路径
2018/03/15 Python
python使用numpy读取、保存txt数据的实例
2018/10/14 Python
PyTorch之图像和Tensor填充的实例
2019/08/18 Python
基于h5py的使用及数据封装代码
2019/12/26 Python
python Popen 获取输出,等待运行完成示例
2019/12/30 Python
联想澳大利亚官网:Lenovo Australia
2018/01/18 全球购物
C#笔试题集合
2013/06/21 面试题
shell程序如何生命变量?shell变量是弱变量吗?
2014/11/10 面试题
银行会计业务的个人自我评价
2013/11/02 职场文书
自我评价个人范文
2013/12/16 职场文书
教师求职信范文分享
2013/12/27 职场文书
清华大学自主招生自荐信
2014/01/29 职场文书
《小草和大树》教学反思
2014/02/16 职场文书
祖国在我心中演讲稿450字
2014/09/05 职场文书
Go 语言下基于Redis分布式锁的实现方式
2021/06/28 Golang