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 相关文章推荐
JS的递增/递减运算符和带操作的赋值运算符的等价式
Dec 08 Javascript
很多人都是用下面的js刷新站IP和PV
Sep 05 Javascript
使用dynatrace-ajax跟踪JavaScript的性能
Apr 12 Javascript
JQuery 动态扩展对象之另类视角
May 25 Javascript
某人初学javascript的时候写的学习笔记
Dec 30 Javascript
JavaScript与Image加载事件(onload)、加载状态(complete)
Feb 14 Javascript
无缝滚动js代码通俗易懂(自写)
Jun 19 Javascript
Vuex之理解Getters的用法实例
Apr 19 Javascript
浅谈js使用in和hasOwnProperty获取对象属性的区别
Apr 27 Javascript
JavaScript复制内容到剪贴板的两种常用方法
Feb 27 Javascript
vue中如何实现后台管理系统的权限控制的方法示例
Sep 19 Javascript
4个顶级JavaScript高级文本编辑器
Oct 10 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
如何让thinkphp在模型中自动完成session赋值小教程
2014/09/05 PHP
Yii2使用dropdownlist实现地区三级联动功能的方法
2016/07/18 PHP
thinkPHP5.0框架事务处理操作简单示例
2018/09/07 PHP
PHP网站常见安全漏洞,及相应防范措施总结
2021/03/01 PHP
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
让ie运行js时提示允许阻止内容运行的解决方法
2010/10/24 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
2013/04/24 Javascript
js读取json的两种常用方法示例介绍
2014/10/19 Javascript
javascript实现字符串反转的方法
2015/02/05 Javascript
详解JavaScript对象和数组
2015/12/03 Javascript
使用JavaScript脚本判断页面是否在微信中被打开
2016/03/06 Javascript
request请求获取参数的实现方法(post和get两种方式)
2016/09/27 Javascript
原生JS实现图片轮播切换效果
2016/12/15 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
JS实现两周内自动登录功能
2017/03/23 Javascript
taro小程序添加骨架屏的实现代码
2019/11/15 Javascript
[01:01:24]DOTA2上海特级锦标赛A组败者赛 EHOME VS CDEC第三局
2016/02/25 DOTA
[24:42]VP vs TNC Supermajor小组赛B组 BO3 第三场 6.2
2018/06/03 DOTA
[01:06] DOTA2英雄背景故事第三期之秩序法则光之守卫
2020/07/07 DOTA
Python 读写文件和file对象的方法(推荐)
2016/09/12 Python
Python实现图片拼接的代码
2018/07/02 Python
python: 判断tuple、list、dict是否为空的方法
2018/10/22 Python
python3 实现一行输入,空格隔开的示例
2018/11/14 Python
详解Django配置优化方法
2019/11/18 Python
python连接打印机实现打印文档、图片、pdf文件等功能
2020/02/07 Python
Python 解决火狐浏览器不弹出下载框直接下载的问题
2020/03/09 Python
python中用Scrapy实现定时爬虫的实例讲解
2021/01/18 Python
css3 flex布局 justify-content:space-between 最后一行左对齐
2020/01/02 HTML / CSS
印尼美容产品购物网站:PerfectBeauty.id
2017/12/01 全球购物
达拉斯牛仔官方商店:Dallas Cowboys Pro Shop
2018/02/10 全球购物
安全生产承诺书
2014/03/26 职场文书
共产党员公开承诺践诺书
2014/05/28 职场文书
诚信考试标语
2014/06/24 职场文书
2014年资料员工作总结
2014/11/18 职场文书
2015年学校政教处工作总结
2015/05/26 职场文书
换届选举主持词
2015/07/03 职场文书