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 load()在firefox(火狐)下显示不正常的解决方法
Apr 05 Javascript
js 去除字符串第一位逗号的方法
Jun 07 Javascript
探寻Javascript执行效率问题
Nov 12 Javascript
JS获取及设置TextArea或input文本框选择文本位置的方法
Mar 24 Javascript
JavaScript中的对象继承关系
Aug 01 Javascript
canvas压缩图片转换成base64格式输出文件流
Mar 09 Javascript
简单实现jQuery弹窗效果
Oct 30 jQuery
Angular 项目实现国际化的方法
Jan 08 Javascript
微信小程序 checkbox使用实例解析
Sep 09 Javascript
深入探索VueJS Scoped CSS 实现原理
Sep 23 Javascript
Vue项目结合Vue-layer实现弹框式编辑功能(实例代码)
Mar 11 Javascript
vue过滤器实现日期格式化的案例分析
Jul 02 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
ThinkPHP3.0略缩图不能保存到子目录的解决方法
2012/09/30 PHP
PHP实现关键字搜索后描红功能示例
2019/07/03 PHP
模仿jQuery each函数的链式调用
2009/07/22 Javascript
JavaScript 函数调用规则
2009/09/14 Javascript
Javascript页面添加到收藏夹的简单方法
2013/08/07 Javascript
js限制文本框只能输入中文的方法
2015/08/11 Javascript
JS调用打印机功能简单示例
2016/11/28 Javascript
微信小程序实现皮肤功能(夜间模式)
2017/06/18 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
详解webpack+gulp实现自动构建部署
2017/06/29 Javascript
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
使用 vue.js 构建大型单页应用
2018/02/10 Javascript
nodeJS模块简单用法示例
2018/04/21 NodeJs
Vue组件之极简的地址选择器的实现
2018/05/31 Javascript
ES6的异步终极解决方案分享
2019/07/11 Javascript
vue源码nextTick使用及原理解析
2019/08/13 Javascript
Postman参数化实现过程及原理解析
2020/08/13 Javascript
前端性能优化建议
2020/09/17 Javascript
JQuery绑定事件四种实现方法解析
2020/12/02 jQuery
[54:24]Optic vs TNC 2018国际邀请赛小组赛BO2 第二场
2018/08/18 DOTA
python模拟enum枚举类型的方法小结
2015/04/30 Python
python入门基础之用户输入与模块初认识
2016/11/14 Python
python+matplotlib实现鼠标移动三角形高亮及索引显示
2018/01/15 Python
python3获取当前文件的上一级目录实例
2018/04/26 Python
完美解决安装完tensorflow后pip无法使用的问题
2018/06/11 Python
使用python对excle和json互相转换的示例
2018/10/23 Python
详解用python生成随机数的几种方法
2019/08/04 Python
python 爬取B站原视频的实例代码
2020/09/09 Python
Python 虚拟环境工作原理解析
2020/12/24 Python
意大利自行车商店:Cingolani Bike Shop
2019/09/03 全球购物
Carolina Lemke Berlin澳大利亚官网:时尚太阳镜品牌
2019/09/17 全球购物
会计实习自我鉴定
2013/12/04 职场文书
出国签证在职证明范本
2014/11/24 职场文书
化妆品促销活动总结
2015/05/07 职场文书
创业计划书介绍
2019/04/24 职场文书
Python利用folium实现地图可视化
2021/05/23 Python