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 相关文章推荐
Javascript常考语句107条收集
Mar 09 Javascript
一个简单的Ext.XTemplate的实例代码
Mar 18 Javascript
jquery数组过滤筛选方法grep()简介
Jun 06 Javascript
再分享70+免费的jquery 图片滑块效果插件和教程
Dec 15 Javascript
javascript操作ul中li的方法
May 14 Javascript
jQuery插件pagewalkthrough实现引导页效果
Jul 05 Javascript
JavaScript的函数式编程基础指南
Mar 19 Javascript
需灵活掌握的Bootstrap预定义排版类 你精通吗?
Jun 20 Javascript
深入理解requestAnimationFrame的动画循环
Sep 20 Javascript
微信小程序 网络API Websocket详解
Nov 09 Javascript
基于Vue实现支持按周切换的日历
Sep 24 Javascript
QRCode.js二维码生成并能长按识别
Oct 16 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
利用yahoo汇率接口实现实时汇率转换示例 汇率转换器
2014/01/14 PHP
PHP fopen()和 file_get_contents()应用与差异介绍
2014/03/19 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
2019/04/02 PHP
Laravel框架实现多数据库连接操作详解
2019/07/12 PHP
js自定义事件及事件交互原理概述(二)
2013/02/01 Javascript
innerHTML,outerHTML,innerText,outerText的用法及区别解析
2013/12/16 Javascript
jQuery将多条数据插入模态框的示例代码
2014/09/25 Javascript
PHP实现的各种中文编码转换类分享
2015/01/23 Javascript
js设置document.domain实现跨域的注意点分析
2015/05/21 Javascript
牛叉的Jquery——Jquery与DOM对象的互相转换及DOM的三种操作
2015/10/29 Javascript
jQuery EasyUI 布局之动态添加tabs标签页
2015/11/18 Javascript
JS截取字符串实例详解
2015/11/24 Javascript
jQuery回到顶部的代码
2016/07/09 Javascript
基于jQuery的select下拉框选择触发事件实例分析
2016/11/18 Javascript
ES6入门教程之let和const命令详解
2017/05/17 Javascript
vue实现表格增删改查效果的实例代码
2017/07/18 Javascript
jQuery Easyui Treegrid实现显示checkbox功能
2017/08/08 jQuery
JS设计模式之策略模式概念与用法分析
2018/02/05 Javascript
bootstrap treeview 树形菜单带复选框及级联选择功能
2018/06/08 Javascript
mock.js实现模拟生成假数据功能示例
2019/01/15 Javascript
Python 返回汉字的汉语拼音
2009/02/27 Python
Python遍历目录的4种方法实例介绍
2015/04/13 Python
如何在Django中设置定时任务的方法示例
2019/01/18 Python
python图像处理模块Pillow的学习详解
2019/10/09 Python
使用Python完成15位18位身份证的互转功能
2019/11/06 Python
用Python 执行cmd命令
2020/12/18 Python
CSS3 实现飘动的云朵动画
2020/12/01 HTML / CSS
西班牙电子产品购物网站:Electronicamente
2018/07/26 全球购物
Senreve官网:美国旧金山的奢侈手袋品牌
2019/03/21 全球购物
美工的岗位职责
2013/11/14 职场文书
八项规定整改措施
2014/02/12 职场文书
2014镇党委书记党建工作汇报材料
2014/11/02 职场文书
武夷山导游词
2015/02/03 职场文书
物流仓管员岗位职责
2015/04/01 职场文书
实例详解Python的进程,线程和协程
2022/03/13 Python
mysql 8.0.27 绿色解压版安装教程及配置方法
2022/04/20 MySQL