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 相关文章推荐
window.event.keyCode兼容IE和Firefox实现js代码
May 30 Javascript
JS中图片缓冲loading技术的实例代码
Aug 29 Javascript
JQuery结合CSS操作打印样式的方法
Dec 24 Javascript
一段非常简单的js判断浏览器的内核
Aug 17 Javascript
JS判断字符串变量是否含有某个字串的实现方法
Jun 03 Javascript
js实现短信发送倒计时功能(正则验证)
Feb 10 Javascript
js实现截图保存图片功能的代码示例
Feb 16 Javascript
JavaScript实现浅拷贝与深拷贝的方法分析
Jul 05 Javascript
vue鼠标悬停事件实例详解
Apr 01 Javascript
Vue开发之封装分页组件与使用示例
Apr 25 Javascript
微信小程序 简易计算器实现代码实例
Sep 02 Javascript
Javascript基于OOP实实现探测器功能代码实例
Aug 26 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将向Java靠拢
2006/10/09 PHP
深入php之规范编程命名小结
2013/05/15 PHP
访问编码后的中文URL返回404错误的解决方法
2014/08/20 PHP
PHP实现CSV文件的导入和导出类
2015/03/24 PHP
php实现zip文件解压操作
2015/11/03 PHP
PHP中的print_r 与 var_dump 输出数组
2016/06/13 PHP
PHP之header函数详解
2021/03/02 PHP
基于JQuery的cookie插件
2010/04/07 Javascript
JavaScript入门之基本函数详解
2011/10/21 Javascript
使用javascript实现页面定时跳转总结篇
2013/09/21 Javascript
jQuery函数map()和each()介绍及异同点分析
2014/11/08 Javascript
jQuery实现下滑菜单导航效果代码
2015/08/25 Javascript
浅谈JS正则表达式的RegExp对象和括号的使用
2016/07/28 Javascript
Vue.js每天必学之表单控件绑定
2016/09/05 Javascript
BootStrap与Select2使用小结
2017/02/17 Javascript
jQuery插件FusionWidgets实现的Bulb图效果示例【附demo源码下载】
2017/03/23 jQuery
使用vue实现grid-layout功能实例代码
2018/01/05 Javascript
VUE2.0+Element-UI+Echarts封装的组件实例
2018/03/02 Javascript
解决layui调用自定义方法提示未定义的问题
2019/09/14 Javascript
基于jQuery拖拽事件的封装
2020/11/29 jQuery
Python3中的2to3转换工具使用示例
2015/06/12 Python
Python基于Floyd算法求解最短路径距离问题实例详解
2018/05/16 Python
5分钟 Pipenv 上手指南
2018/12/20 Python
python整合ffmpeg实现视频文件的批量转换
2019/05/31 Python
python自动化测试之DDT数据驱动的实现代码
2019/07/23 Python
TensorFlow2.0:张量的合并与分割实例
2020/01/19 Python
浅谈pytorch池化maxpool2D注意事项
2020/02/18 Python
Python脚本破解压缩文件口令实例教程(zipfile)
2020/06/14 Python
大专计算机个人求职的自我评价
2013/10/21 职场文书
函授毕业生的自我鉴定
2013/11/26 职场文书
高中语文教学反思
2014/01/16 职场文书
运动会邀请函范文
2014/02/06 职场文书
幼儿园五一活动方案
2014/02/07 职场文书
2014年环保局工作总结
2014/12/11 职场文书
幼儿园教师工作总结2015
2015/04/02 职场文书
2016年万圣节家长开放日活动总结
2016/04/05 职场文书