开发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 相关文章推荐
基于jquery tab切换(防止页面刷新)
May 23 Javascript
JS获取各种浏览器窗口大小的方法
Jan 14 Javascript
Javascript 实现复制(Copy)动作方法大全
Jun 20 Javascript
JS 实现倒计时数字时钟效果【附实例代码】
Mar 30 Javascript
jQuery仿京东商城楼梯式导航定位菜单
Jul 25 Javascript
微信小程序 POST请求(网络请求)详解及实例代码
Nov 16 Javascript
jQuery中on方法使用注意事项详解
Feb 15 Javascript
基于react框架使用的一些细节要点的思考
May 31 Javascript
ES6中新增的Object.assign()方法详解
Sep 22 Javascript
JS+jQuery实现注册信息的验证功能
Sep 26 jQuery
Vue 2.0学习笔记之使用$refs访问Vue中的DOM
Dec 19 Javascript
详解vue开发中调用微信jssdk的问题
Apr 16 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
PHP管理内存函数 memory_get_usage()使用介绍
2012/09/23 PHP
如何用PHP实现插入排序?
2013/04/10 PHP
Session服务器配置指南与使用经验的深入解析
2013/06/17 PHP
输入值/表单提交参数过滤有效防止sql注入的方法
2013/12/25 PHP
PHP入门教程之PHP操作MySQL的方法分析
2016/09/11 PHP
PHP压缩图片功能的介绍
2019/03/21 PHP
在视频前插入广告
2006/11/20 Javascript
JQuery 1.6发布 性能提升,同时包含大量破坏性变更
2011/05/10 Javascript
基于jquery tab切换(防止页面刷新)
2012/05/23 Javascript
js 在定义的时候立即执行的函数表达式(function)写法
2013/01/16 Javascript
JavaScript获取XML数据附示例截图
2014/03/05 Javascript
jQuery实现瀑布流的取巧做法分享
2015/01/12 Javascript
Bootstrap3.0学习教程之JS折叠插件
2016/05/27 Javascript
深入分析node.js的异步API和其局限性
2016/09/05 Javascript
利用bootstrapValidator验证UEditor
2016/09/14 Javascript
js实现前端分页页码管理
2017/01/06 Javascript
使用bat打开多个cmd窗口执行gulp、node
2017/02/17 Javascript
js for循环倒序输出数组元素的实例
2017/03/01 Javascript
解决Vue使用mint-ui loadmore实现上拉加载与下拉刷新出现一个页面使用多个上拉加载后冲突问题
2017/11/07 Javascript
node.js用fs.rename强制重命名或移动文件夹的方法
2017/12/27 Javascript
JavaScript的Object.defineProperty详解
2018/07/09 Javascript
js+springMVC 提交数组数据到后台的实例
2019/09/21 Javascript
vue组件内部引入外部js文件的方法
2020/01/18 Javascript
angular组件间传值测试的方法详解
2020/05/07 Javascript
Python中Random和Math模块学习笔记
2015/05/18 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
python使用布隆过滤器的实现示例
2020/08/20 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
Mybag美国/加拿大:英国奢华包包和名牌手袋网站
2020/02/16 全球购物
2014年基层党组织公开承诺书
2014/03/29 职场文书
五四青年节演讲稿
2014/05/26 职场文书
学校领导班子群众路线整改措施
2014/09/16 职场文书
夫妻忠诚协议范文
2014/11/16 职场文书
无罪辩护词范文
2015/05/21 职场文书
关于践行三严三实的心得体会
2016/01/05 职场文书
golang 在windows中设置环境变量的操作
2021/04/29 Golang