您好,登錄后才能下訂單哦!
這篇文章主要介紹“Vue中如何實現一個樹形組件”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“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就沒有自己的上下文,而可以直接引入父組件的上下文,這樣模式應該在很多場合均會使用到的。
關于“Vue中如何實現一個樹形組件”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。