vuejs使用递归组件实现树形目录的方法


Posted in Javascript onSeptember 30, 2017

上篇文章我提到了通讯录的开发,里面的目录使用了vue的递归组件实现的树形目录,这篇文章就来讲讲如何实现树形目录吧!

首先实现效果如下,觉得菜单还是比较nice的是吧:

vuejs使用递归组件实现树形目录的方法

这边数据调用的是数据库的数据的,需要数据库进行数据的构造,这里涉及到java的构造多叉树的知识,后续我会另外写一篇文章详细讲解,这里讲下前端。

数据可以先构造json使用,这里用到的格式大概如下,以childList来嵌套子菜单:

{
  id:YH, 
  name:银行, 
  pid:0, 
  childList:[{
    id:YH******, 
    name:国家开发银行, 
    pid:YH, 
    childList:[{
      id:YH*****3, 
      name:国家开发银行香港分行, 
      pid:YH******, 
      childList:[]
    }, 
    {
      id=YH*****1, 
      name=国家开发银行广东省分行, 
      pid=YH******, 
      childList=[]
    }, {
      id=YH*****2, 
      name=国家开发银行深圳分行, 
      pid=YH******, 
      childList=[]
    }
  ]}
}

按照思路,我们是要ul里面套li,li里面套ul,这样无限套用,所以在子组件里面这么写:

<li>
  <div>
   <i @click='toggle' v-if='isFolder' class="mui-icon iconfont" :class="[open?'icon-wenjianjia':'icon-wenjianjiaguanbi']"></i>
   <!--isFolder判断是否存在子级改变图标-->
   <i @click='toggle' class="mui-icon iconfont icon-wenjian" style="color: #00ccff" v-else></i>
   <!--这里用到的方法是给父组件传值,具体可看上一篇文章-->
   <span @click="propInstCode(model);propInstName(model)">
    {{model.name}}
   </span>
  </div>
  <ul v-show="open" v-if='isFolder'>
   <tree-menu v-for='cel in model.childList' :model='cel'></tree-menu>
  </ul>
 </li>

在官方文档里面强调了name属性,所以我们在开始还要定义name,这边的name用到的是上面的tree-menu:

export default {
  name: 'treeMenu',
  props: ['model'],
  components: {}
}

按照vue的思想,不操作Dom树,我们定义两个变量,一个显示隐藏子菜单(open),一个存不存子菜单修改图标(isFolder)。

data() {
   return {
    open: false,
    isFolder: true,
   }
 },

我是参照一篇文章编写的,在这一步说的是“利用vue计算属性动态改变isFolder的值,修改图标,判断存在不子级和子级长度”

computed: {
  isFolder() {
    return this.model.childTreeNode && this.model.childTreeNode.length
  }
}

这里就出现了个问题,会一直不停地报错:

vuejs使用递归组件实现树形目录的方法

找了很久的问题,结果我是这样解决的,去掉computed的计算属性,将其放到created里面:

created(){
   //将isFolder放在这里判断可以识别出最底层菜单,然后改变图标,放在computed的话会一直报错并识别不出最底层菜单改变样式
   this.isFolder = this.model.childList && this.model.childList.length;
  }

显示/隐藏事件

methods: {
   toggle: function() {
    if(this.isFolder){
     this.open = !this.open;
    }
   },
}

到这里就构造好树形目录的组件了,只要在相应的父组件里面调用就行了,完整代码如下:

父组件中引用

<ul class="tree_container" v-for="item in list">
  <my-menu-tree :model='item' :instType='this.instType'></my-menu-tree>
</ul>

子组件:

<template>
 <li>
  <div>
   <i @click='toggle' v-if='isFolder' class="mui-icon iconfont" :class="[open?'icon-wenjianjia':'icon-wenjianjiaguanbi']"></i>
   <!--isFolder判断是否存在子级改变图标-->
   <i @click='toggle' class="mui-icon iconfont icon-wenjian" style="color: #00ccff" v-else></i>
   <span @click="propInstCode(model);propInstName(model)">
    {{model.name}}
   </span>
  </div>
  <ul v-show="open" v-if='isFolder'>
   <tree-menu v-for='cel in model.childList' :model='cel'></tree-menu>
  </ul>
 </li>
</template>
<script type="text/javascript">
 import {bus} from '../../bus.js'
 export default {
  name: 'treeMenu',
  props: ['model','instType'],
  components: {},
  data() {
   return {
    open: false,
    isFolder: true,
   }
  },
  computed: {
  },
  methods: {
   toggle: function() {
    if(this.isFolder){
     this.open = !this.open;
    }
   },
   //通过总线将值传给父组件
   propInstCode:function (model) {
    //$emit触发当前实例事件
     bus.$emit('custTreeSay',this.model.id);
   },
   propInstName:function (model) {
    bus.$emit('custTreeSayName',this.model.name);
   }
  },
  created(){
   //将isFolder放在这里判断可以识别出最底层菜单,然后改变图标,放在computed的话会一直报错并识别不出最底层菜单改变样式
   this.isFolder = this.model.childList && this.model.childList.length;
  }
 }
</script>

<style lang="less" rel="stylesheet/less" scoped>
 ul {
  list-style: none;
  padding-left: 20px;
 }
 ul li{
  list-style: none;
 }
 a{
  color: #404040;
  //text-decoration: underline;
 }
 i.icon {
  display: inline-block;
  width: 15px;
  height: 15px;
  background-repeat: no-repeat;
  vertical-align: middle;
 }
 i{
  opacity: 0.8;
  color: #f0ad4e;
 }
 .tree-menu li {
  line-height: 1.5;
 }
</style>

子组件可以直接使用,样式也一起贴出来了,但是在父组件中也有点样式,就留给你们自己操作了,这个完整的代码里面还包括了上篇文章提到的组件传值的部分。

我的icon用的是阿里的iconfont,大家也可以百度搜一下

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
可以显示单图片,多图片ajax请求的ThickBox3.1类下载
Dec 23 Javascript
简洁Ajax函数处理(示例代码)
Nov 15 Javascript
iframe中子父类窗口调用JS的方法及注意事项
Aug 25 Javascript
jquery实现未经美化的简洁TAB菜单效果
Aug 28 Javascript
基于Vue2实现的仿手机QQ单页面应用功能(接入聊天机器人 )
Mar 30 Javascript
angularjs使用gulp-uglify压缩后执行报错的解决方法
Mar 07 Javascript
vue.js父子组件通信动态绑定的实例
Sep 28 Javascript
15分钟深入了解JS继承分类、原理与用法
Jan 19 Javascript
微信小程序结合mock.js实现后台模拟及调试
Mar 28 Javascript
jQuery实现消息弹出框效果
Dec 10 jQuery
如何在vue中使用video.js播放m3u8格式的视频
Feb 01 Vue.js
利用 JavaScript 构建命令行应用
Nov 17 Javascript
Easy UI动态树点击文字实现展开关闭功能
Sep 30 #Javascript
js实现轮播图的两种方式(构造函数、面向对象)
Sep 30 #Javascript
React实践之Tree组件的使用方法
Sep 30 #Javascript
JS动态添加的div点击跳转到另一页面实现代码
Sep 30 #Javascript
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
Sep 30 #Javascript
jqgrid实现简单的单行编辑功能
Sep 30 #Javascript
微信小程序富文本渲染引擎的详解
Sep 30 #Javascript
You might like
php单例模式实现方法分析
2015/03/14 PHP
php实现统计目录文件大小的函数
2015/12/25 PHP
Composer设置忽略版本匹配的方法
2016/04/27 PHP
CodeIgniter记录错误日志的方法全面总结
2016/05/17 PHP
PHP cURL获取微信公众号access_token的实例
2018/04/28 PHP
php操作mongodb封装类与用法实例
2018/09/01 PHP
javascript 面向对象编程基础:封装
2009/08/21 Javascript
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
javascript开发技术大全-第1章javascript概述
2011/07/03 Javascript
jquery Mobile入门—外部链接切换示例代码
2013/01/08 Javascript
用jquery仿做发微博功能示例
2014/04/18 Javascript
jQuery实现的Div窗口震动特效
2014/06/09 Javascript
Bootstrap每天必学之前端开发框架
2015/11/19 Javascript
Bootstrap中点击按钮后变灰并显示加载中实例代码
2016/09/23 Javascript
使用vue实现点击按钮滑出面板的实现代码
2017/01/10 Javascript
基于 D3.js 绘制动态进度条的实例详解
2018/02/26 Javascript
解决Vue axios post请求,后台获取不到数据的问题方法
2018/08/11 Javascript
对vue v-if v-else-if v-else 的简单使用详解
2018/09/29 Javascript
通过layer实现可输入的模态框的例子
2019/09/27 Javascript
Nuxt配置Element-UI按需引入的操作方法
2020/07/06 Javascript
[06:15]2016国际邀请赛中国区预选赛单车采访:我顶WINGS
2016/06/27 DOTA
跟老齐学Python之使用Python操作数据库(1)
2014/11/25 Python
python中子类调用父类函数的方法示例
2017/08/18 Python
Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法
2019/12/17 Python
基于Python爬虫采集天气网实时信息
2020/06/05 Python
Python 程序报错崩溃后如何倒回到崩溃的位置(推荐)
2020/06/23 Python
Python unittest如何生成HTMLTestRunner模块
2020/09/08 Python
使用Python提取文本中含有特定字符串的方法示例
2020/12/09 Python
HTML5使用drawImage()方法绘制图像
2014/06/23 HTML / CSS
商学院大学生求职的自我评价
2014/03/12 职场文书
大学班级计划书
2014/04/29 职场文书
学校关爱留守儿童活动方案
2014/08/27 职场文书
志愿者爱心公益活动策划方案
2014/09/15 职场文书
三傻大闹宝莱坞观后感
2015/06/03 职场文书
2015年依法治校工作总结
2015/07/27 职场文书
学雷锋广播稿大全
2015/08/19 职场文书