开发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 相关文章推荐
Js 本页面传值实现代码
May 17 Javascript
javascript 获取元素位置的快速方法 getBoundingClientRect()
Nov 26 Javascript
深入理解JavaScript系列(12) 变量对象(Variable Object)
Jan 16 Javascript
js弹出窗口之弹出层的小例子
Jun 17 Javascript
Jquery和JS用外部变量获取Ajax返回的参数值的方法实例(超简单)
Jun 17 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
Oct 22 Javascript
关于JavaScript作用域你想知道的一切
Feb 04 Javascript
基于javascript实现全屏漂浮广告
Mar 31 Javascript
jquery css实现邮箱自动补全
Nov 14 Javascript
基于JavaScript实现自动更新倒计时效果
Dec 19 Javascript
node.js实现复制文本到剪切板的功能
Jan 23 Javascript
Javascript节流函数throttle和防抖函数debounce
Dec 03 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
javascript document.referrer 用法
2009/04/30 Javascript
js onload处理html页面加载之后的事件
2013/10/30 Javascript
AngularJS入门教程(零):引导程序
2014/12/06 Javascript
JavaScript实现带标题的图片轮播特效
2015/05/20 Javascript
使用jquery动态加载Js文件和Css文件
2015/10/24 Javascript
JS获取checkbox的个数简单实例
2016/08/19 Javascript
微信小程序遇到修改数据后页面不渲染的问题解决
2017/03/09 Javascript
js中DOM三级列表(代码分享)
2017/03/20 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
underscore之Collections_动力节点Java学院整理
2017/07/10 Javascript
实例详解JSON取值(key是中文或者数字)方式
2017/08/24 Javascript
vue文件树组件使用详解
2018/03/29 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
vue项目打包之后背景样式丢失的解决方案
2019/01/17 Javascript
浅谈layui数据表格判断问题(加入表单元素),设置单元格样式
2019/10/26 Javascript
Element Tooltip 文字提示的使用示例
2020/07/26 Javascript
[02:40]DOTA2英雄基础教程 巨牙海民
2013/12/23 DOTA
初学Python函数的笔记整理
2015/04/07 Python
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
基于pip install django失败时的解决方法
2018/06/12 Python
python 对给定可迭代集合统计出现频率,并排序的方法
2018/10/18 Python
Python datetime和unix时间戳之间相互转换的讲解
2019/04/01 Python
python+OpenCV实现车牌号码识别
2019/11/08 Python
澳大利亚办公室装修:JasonL Office Furniture
2019/06/25 全球购物
微软马来西亚官方网站:Microsoft马来西亚
2019/11/22 全球购物
师说教学反思
2014/02/07 职场文书
招聘专员岗位职责
2014/03/07 职场文书
祖国在我心中演讲稿400字
2014/05/04 职场文书
爱祖国演讲稿
2014/05/04 职场文书
婚礼秀策划方案
2014/05/19 职场文书
课外小组活动总结
2014/08/27 职场文书
简历自我评价模板
2015/03/11 职场文书
学校光盘行动倡议书
2015/04/28 职场文书
python实现的人脸识别打卡系统
2021/05/08 Python
MySQL数据库完全卸载的方法
2022/03/03 MySQL
MySQL 计算连续登录天数
2022/05/11 MySQL