开发Vue树形组件的示例代码


Posted in Javascript onDecember 21, 2017

本文介绍了Vue树形组件的示例代码,分享给大家,具体如下:

使用SemanticUI和vue做一个menubar组件,实现方法大概是这样的:

<template> 
  <div class="ui menu"> 
   <template v-for="item in leftItems"> 
    <a " v-if="!item.children" @click="item.click"> 
     <i class="{{ item.icon }} icon" v-if="item.icon"></i>{{item.text}} 
     <div class="ui mini {{item.labelColor }} label" v-if="item.label"> 
      {{item.label}} 
     </div> 
    </a>  
   //如果有有children则说明是下拉菜单项,然后递归调用自身 
    <template v-else="item.children.length > 0"> 
     <div class="ui dropdown item"> 
      <i class="{{ item.icon }} icon" v-if="item.icon"></i>   
      <div class="text"> {{item.text}}</div> 
      <menubar :items="item.children" ></menubar> 
     </div> 
    </template> 
   </template> 
  //显示在右侧的菜单项,也是递归调用自身 
   <menubar :items="rightItems" v-if="rightItems.length > 0"></menubar> 
  </div> 
</template>

使用时,假如父组件app使用到了menubar组件,那么data中需要定义一下items数据,例 :

menubar:[ 
     {id:"a",text:"主页1",icon:"home",tips:"提示",label:"33",labelColor:"red",url:"#"}, 
     {id:"b",text:"菜单",icon:"edit",tips:"提示",url:"#",children:[ 
       {id:"a",text:"菜单1",click:"test3",icon:"home",url:"#"}, 
       {id:"a",text:"菜单2",click:"test3",icon:"home",url:"#"} 
     ]}, 
     {id:"bb",text:"编辑",tab:"a",icon:"user",vlink:"#"}, 
     {id:"bb",text:"文件",tab:"b",icon:"user",click:"test1"}, 
     {id:"bb",text:"帮助",tab:"c",icon:"help",click:"test2"}, 
     {id:"bb",text:"工具",icon:"user",url:"www.baidu.com"}, 
     {id:"c",text:"设置",icon:"home",tips:"提示",enabled:true,color:"blue",url:"#",right:true,label:"",children:[ 
        {id:"bbb",text:"配置",icon:"home",tips:"提示",click:"test3"}, 
        {id:"adsd",text:"退出",icon:"home",tips:"提示",vlink:"/workdesk",url:"#"} 
        ] 
      } 
   ]

里面的click事件是定义了,当在工具栏中单击时的事件,理想的情况应该是事件定义在父组件app的events里面,像这样:

events:{ 
  eventa:function(){....}, 
  eventb:function(){....}, 
}

工具栏组件是根据传入的items来生成的,包括里面的子组件。最终工具栏组件的结构就是一个树状结构,例似这样的:

MenuBar
--MenuBar                   
----MenuBar
-----MenuBar
--Menubar

由于每个工具栏组件里面的每个Menubar均有自己的上下文,这样当子组件Menubar的click事件触发时并不会调用到顶层app组件events里面定义的事件,而只是调用了父Menubar的events事件。

但是在使用体验上,很明显,工具栏组件的点击事件定义应该是定义在app组件的events里面的才是合理。我们希望menubar:[]定义菜单项时,不管多少级嵌套,事件的触发均可以冒泡到最上面的menubar的父上面。
因此,要实现该机制,目前是采用组件之间的通讯机制来实现的:

<a @click="onMenuItemClick(item,$event)" data-tab="{{item.tab}}" v-link="item.vlink" href="{{item.url}}" rel="external nofollow" v-if="!item.children" :class="[{'active':item.active==true,'disabled':item.enabled==false},item.color,'item']" title="{{item.tips}}"> 
     <i class="{{ item.icon }} icon" v-if="item.icon"></i>{{item.text}} 
     <div class="ui mini {{item.labelColor }} label" v-if="item.label"> 
      {{item.label}} 
     </div> 
    </a>

上面定义一个事件@click="onMenuItemClick(item,$event)"

methods:{ 
  onMenuItemClick:function(item,$event){    
   if(this.subMenu){ 
    this.$dispatch("menuItemClick",item,$event)  
   }else{ 
    if(item.click){ 
     this.$parent.$emit(item.click,item) 
    } 
   }   
  } 
 }

在onMenuItemClick触发时,我们根据传入的subMenu来确认点击事件如何处理,如果Menubar是作为子菜单栏处理,则我们就直接向上冒泡事件,否则就在上层父组件触发事件。

<menubar  @menuItemClick="onMenuItemClick" :items="rightItems" sub-menu="true" v-if="rightItems.length > 0"></menubar>

在menubar组件内部调用时就传入submenu=true,并且侦听事件menuItemClick,menuItemClick事件代码这样:

events:{ 
  menuItemClick:function(item,$event){ 
   if(!this.subMenu){ 
    this.$parent.$emit(item.click,item) 
   }else{ 
    return true 
   } 
  } 
 },

小结一下:

在处理嵌套结构的组件,如具有下拉菜单的工具栏、树形组件等时,由于组件内部均具有各自独立的上下文,因此必须使用组件通讯机制来处理内部组件间的通讯。

但如此处理方式,我觉得还是比较麻烦的,理想的方式,我觉得最好的官方可以为组件提供一个直接使用父组件上下文的机制,例如:

<MenuBar> 
 <button scoped="false"></button> 
<button scoped="false"></button> 
</MenuBar>

这样上面的button就没有自己的上下文,而可以直接引入父组件的上下文,这样模式应该在很多场合均会使用到的。

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

Javascript 相关文章推荐
JavaScript 常见安全漏洞和自动化检测技术
Aug 21 Javascript
Easyui Treegrid改变默认图标的方法
Apr 29 Javascript
对jQuary选择器的全面总结
Jun 20 Javascript
js 动态给元素添加、移除事件的实现方法
Jul 19 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
Nov 17 Javascript
前端分页功能的实现以及原理(jQuery)
Jan 22 Javascript
超简单的Vue.js环境搭建教程
Mar 17 Javascript
React简单介绍
May 24 Javascript
React Native 使用Fetch发送网络请求的示例代码
Dec 02 Javascript
Js中使用正则表达式验证输入是否有特殊字符
Sep 07 Javascript
解决LayUI数据表格复选框不居中显示的问题
Sep 25 Javascript
vue3不同环境下实现配置代理
May 25 Vue.js
详解使用vuex进行菜单管理
Dec 21 #Javascript
Angular5.1新功能分享
Dec 21 #Javascript
vue2中的keep-alive使用总结及注意事项
Dec 21 #Javascript
webpack写jquery插件的环境配置
Dec 21 #jQuery
基于Vue 2.0的模块化前端 UI 组件库小结
Dec 21 #Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
Dec 21 #Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
Dec 20 #Javascript
You might like
PHP 生成的XML以FLASH获取为乱码终极解决
2009/08/07 PHP
PHP 编写大型网站问题集
2010/05/07 PHP
PHP封装的HttpClient类用法实例
2015/06/17 PHP
javascript基础之查找元素的详细介绍(访问节点)
2013/07/05 Javascript
js使浏览器窗口最大化实现代码(适用于IE)
2013/08/07 Javascript
javascript实现促销倒计时+fixed固定在底部
2013/09/18 Javascript
如何判断鼠标是否在DIV的区域内
2013/11/13 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
JavaScript获取页面上被选中文字的方法技巧
2015/03/13 Javascript
JavaScript 匿名函数和闭包介绍
2015/04/13 Javascript
简单实现限制uploadify上传个数
2015/11/16 Javascript
浅谈js中对象的使用
2016/08/11 Javascript
[原创]javascript typeof id==='string'?document.getElementById(id):id解释
2016/11/02 Javascript
JS正则子匹配实例分析
2016/12/22 Javascript
AngularJS中update两次出现$promise属性无法识别的解决方法
2017/01/05 Javascript
ajax实现动态下拉框示例
2017/01/10 Javascript
Mac下使用charles遇到的问题以及解决办法
2017/01/10 Javascript
Jquery根据浏览器窗口改变调整大小的方法
2017/02/07 Javascript
Angular.js去除页面中显示的空行方法示例
2017/03/30 Javascript
高性能的javascript之加载顺序与执行原理篇
2018/01/14 Javascript
JS根据json数组多个字段排序及json数组常用操作
2019/06/06 Javascript
[03:02]生活中的Dendi之野外度假篇
2016/08/09 DOTA
python3中str(字符串)的使用教程
2017/03/23 Python
Django 权限认证(根据不同的用户,设置不同的显示和访问权限)
2019/07/24 Python
python中自带的三个装饰器的实现
2019/11/08 Python
Python常用类型转换实现代码实例
2020/07/28 Python
Python lambda表达式原理及用法解析
2020/08/18 Python
Python使用xpath实现图片爬取
2020/09/16 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
2021/01/15 Python
Internal修饰符有什么含义
2013/07/10 面试题
大学生怎样写好自荐信
2014/02/25 职场文书
学校会议通知范文
2015/04/15 职场文书
生产现场禁烟通知
2015/04/23 职场文书
2015年计算机教师工作总结
2015/07/22 职场文书
Nginx部署vue项目和配置代理的问题解析
2021/08/04 Servers
JavaScript实例 ODO List分析
2022/01/22 Javascript