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 相关文章推荐
js常用排序实现代码
Dec 28 Javascript
根据邮箱的域名跳转到相应的登录页面的代码
Feb 27 Javascript
js自动生成对象的属性示例代码
Oct 28 Javascript
jquery prop的使用介绍及与attr的区别
Dec 19 Javascript
使用jquery菜单插件HoverTree仿京东无限级菜单
Dec 18 Javascript
Bootstrap 3多级下拉菜单实例
Nov 23 Javascript
实例教学如何写vue插件
Nov 30 Javascript
vue实现配置全局访问路径头(axios)
Nov 01 Javascript
使用preload预加载页面资源时注意事项
Feb 03 Javascript
React冒泡和阻止冒泡的应用详解
Aug 18 Javascript
springboot+vue实现文件上传下载
Nov 17 Vue.js
vue实现锚点定位功能
Jun 29 Vue.js
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写杨辉三角实例代码
2011/07/17 PHP
discuz程序的PHP加密函数原理分析
2011/08/05 PHP
PHP连接局域网MYSQL数据库的简单实例
2013/08/26 PHP
php实现数字补零的方法总结
2018/09/12 PHP
PHP实现函数内修改外部变量值的方法示例
2018/12/28 PHP
Thinkphp5.0 框架实现控制器向视图view赋值及视图view取值操作示例
2019/10/12 PHP
Laravel 解决composer相关操作提示php相关异常的问题
2019/10/23 PHP
php7 图形用户界面GUI 开发示例
2020/02/22 PHP
JS中的substring和substr函数的区别说明
2013/05/07 Javascript
javascript实现在某个元素上阻止鼠标右键事件的方法和实例
2014/08/12 Javascript
javascript编写实用的省市选择器
2015/02/12 Javascript
JavaScript判断变量是否为数组的方法(Array)
2016/02/24 Javascript
基于jQuery倒计时插件实现团购秒杀效果
2016/05/13 Javascript
js实现的光标位置工具函数示例
2016/10/03 Javascript
原生js实现弹出层登录拖拽功能
2016/12/05 Javascript
jQuery实现鼠标滑过图片移动特效
2016/12/08 Javascript
详解JavaScript的闭包、IIFE、apply、函数与对象
2016/12/21 Javascript
JavaScript事件对象event用法分析
2018/07/27 Javascript
Django rest framework工具包简单用法示例
2018/07/20 Python
python操作小程序云数据库实现简单的增删改查功能
2019/06/06 Python
python按键按住不放持续响应的实例代码
2019/07/17 Python
对Keras中predict()方法和predict_classes()方法的区别说明
2020/06/09 Python
python中requests模拟登录的三种方式(携带cookie/session进行请求网站)
2020/11/17 Python
CSS3盒子模型详解
2013/04/24 HTML / CSS
德国在线订购鲜花:Fleurop
2018/08/25 全球购物
免税水晶:Duty Free Crystal
2019/05/13 全球购物
日语专业推荐信
2013/11/12 职场文书
大学班级干部的自我评价分享
2014/02/10 职场文书
服装采购员岗位职责
2014/03/15 职场文书
QQ空间主人寄语大全
2014/04/12 职场文书
考博专家推荐信
2014/05/10 职场文书
计算机系本科生求职信
2014/05/31 职场文书
公司仓管员岗位职责
2015/04/01 职场文书
创业计划书之川味火锅店
2019/09/02 职场文书
《妈妈别哭,有我在》读后感3篇
2020/01/13 职场文书
Tomcat项目启动失败的原因和解决办法
2022/04/20 Servers