开发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 相关文章推荐
ext 列表页面关于多行查询的办法
Mar 25 Javascript
JavaScript 页面编码与浏览器类型判断代码
Jun 03 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
Nov 11 Javascript
使用jQuery在对象中缓存选择器的简单方法
Jun 30 Javascript
JavaScript实现弹出模态窗体并接受传值的方法
Feb 12 Javascript
JS动态创建元素的两种方法
Apr 20 Javascript
jQuery中队列queue()函数的实例教程
May 03 Javascript
js鼠标按键事件和键盘按键事件用法实例汇总
Oct 03 Javascript
JavaScript中无法通过div.style.left获取值的解决方法
Feb 19 Javascript
详谈jQuery unbind 删除绑定事件 / 移除标签方法
Mar 02 Javascript
Angularjs按需查询实例代码
Oct 30 Javascript
vue中实现滚动加载更多的示例
Nov 08 Javascript
详解使用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
使用sockets:从新闻组中获取文章(一)
2006/10/09 PHP
ajax缓存问题解决途径
2006/12/06 PHP
使用Sphinx对索引进行搜索
2013/06/25 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
2014/06/09 PHP
PHP lcfirst()函数定义与用法
2019/03/08 PHP
firefox中JS读取XML文件
2006/12/21 Javascript
Mac地址验证的javascript代码
2013/11/09 Javascript
一个奇葩的最短的 IE 版本判断JS脚本
2014/05/28 Javascript
jQuery验证插件 Validate详解
2014/11/20 Javascript
Jquery插件实现点击获取验证码后60秒内禁止重新获取
2015/03/13 Javascript
JavaScript把数组作为堆栈使用的方法
2015/03/20 Javascript
Jquery检验手机号是否符合规则并根据手机号检测结果将提交按钮设为不同状态
2015/11/26 Javascript
js简单实现图片延迟加载的方法
2016/07/19 Javascript
微信小程序 wx:key详细介绍
2016/10/28 Javascript
AngularJS封装指令方法详解
2016/12/12 Javascript
微信小程序数字滚动插件使用详解
2018/02/02 Javascript
jQuery实现新闻播报滚动及淡入淡出效果示例
2018/03/23 jQuery
生产制造追溯系统之再说条码打印
2019/06/03 Javascript
vue+高德地图实现地图搜索及点击定位操作
2020/09/09 Javascript
Python实现给文件添加内容及得到文件信息的方法
2015/05/28 Python
Python 获取div标签中的文字实例
2018/12/20 Python
python numpy 按行归一化的实例
2019/01/21 Python
python SQLAlchemy的Mapping与Declarative详解
2019/07/04 Python
python excel转换csv代码实例
2019/08/26 Python
django框架两个使用模板实例
2019/12/11 Python
使用PyQt的QLabel组件实现选定目标框功能的方法示例
2020/05/19 Python
Python使用Chrome插件实现爬虫过程图解
2020/06/09 Python
使用CSS3来代替JS实现交互
2017/08/10 HTML / CSS
CSS3 对过渡(transition)进行调速以及延时
2020/10/21 HTML / CSS
Sunglasses Shop瑞典:欧洲领先的太阳镜网上商店
2018/04/22 全球购物
审计工作个人的自我评价
2013/12/25 职场文书
学习新党章思想汇报
2014/01/09 职场文书
司机岗位职责
2015/02/04 职场文书
2015年宣传部个人工作总结
2015/05/14 职场文书
学习经验交流会总结
2015/11/02 职场文书
Python图片验证码降噪和8邻域降噪
2021/08/30 Python