开发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功能函数(2009-06-04更新)
Jun 04 Javascript
屏蔽网页右键复制和ctrl+c复制的js代码
Jan 04 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
Jan 23 Javascript
Jquery刷新页面背景图片随机变换的实现方法
Mar 15 Javascript
用JQuery 判断某个属性是否存在hasAttr的解决方法
Apr 26 Javascript
JavaScript 学习笔记之数据类型
Jan 14 Javascript
JavaScript实现仿淘宝商品购买数量的增减效果
Jan 22 Javascript
详解Matlab中 sort 函数用法
Mar 20 Javascript
浅谈jquery.form.js的ajaxSubmit和ajaxForm的使用
Sep 09 Javascript
node学习记录之搭建web服务器教程
Feb 16 Javascript
详解webpack+express多页站点开发
Dec 22 Javascript
微信小程序模板(template)使用详解
Jan 31 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文件上传表单摘自drupal的代码
2011/02/15 PHP
php截取html字符串及自动补全html标签的方法
2015/01/15 PHP
PHP输出日历表代码实例
2015/03/27 PHP
各种快递查询--Api接口
2016/04/26 PHP
js showModalDialog弹出窗口实例详解
2014/01/07 Javascript
实现网页页面跳转的几种方法(meta标签、js实现、php实现)
2014/05/20 Javascript
js图片滚动效果时间可随意设定当鼠标移上去时停止
2014/06/26 Javascript
jQuery中removeProp()方法用法实例
2015/01/05 Javascript
轻量级的原生js日历插件calendar.js使用指南
2015/04/28 Javascript
jquery淡入淡出效果简单实例
2016/01/14 Javascript
检查表单元素的值是否为空的实例代码
2016/06/16 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
2018/05/01 Javascript
详解vue-cli 2.0配置文件(小结)
2019/01/14 Javascript
Js参数RSA加密传输之jsencrypt.js的使用
2020/02/07 Javascript
[05:23]DOTA2-DPC中国联赛2月1日Recap集锦
2021/03/11 DOTA
python Django模板的使用方法(图文)
2013/11/04 Python
菜鸟使用python实现正则检测密码合法性
2016/01/05 Python
Python中最大最小赋值小技巧(分享)
2017/12/23 Python
python pycurl验证basic和digest认证的方法
2018/05/02 Python
python 通过 socket 发送文件的实例代码
2018/08/14 Python
Python读取txt某几列绘图的方法
2018/10/14 Python
python从子线程中获得返回值的方法
2019/01/30 Python
Django 创建后台,配置sqlite3教程
2019/11/18 Python
解决python web项目意外关闭,但占用端口的问题
2019/12/17 Python
jupyter notebook 实现matplotlib图动态刷新
2020/04/22 Python
CSS实现鼠标滑过鼠标点击代码写法
2016/12/26 HTML / CSS
html5中canvas学习笔记2-判断浏览器是否支持canvas
2013/01/06 HTML / CSS
奥地利度假券的专家:we-are.travel
2019/04/10 全球购物
保研推荐信格式
2015/03/25 职场文书
司机岗位职责范本
2015/04/10 职场文书
人与自然的观后感
2015/06/18 职场文书
Html5调用企业微信的实现
2021/04/16 HTML / CSS
Python基础之字符串格式化详解
2021/04/21 Python
基于Python编写简易版的天天跑酷游戏的示例代码
2022/03/23 Python
科学家测试在太空中培育人造肉,用于未来太空旅行
2022/04/29 数码科技
vue-cli3.x配置全局的scss的时候报错问题及解决
2022/04/30 Vue.js