Tree 組件是遞歸類組件的典型表明,它經常使用於文件夾、組織架構、生物分類、國家地區等等,世間萬物的大多數結構都是樹形結構。使用樹控件能夠完整展示其中的層級關係,並具備展開收起選擇等交互功能。
如圖所示,咱們要實現的就是這樣一個效果。以前咱們寫樹狀結構都是用jQuery來實現的,用Vue怎麼實現呢?vue
menuList:[
{
title:'菜單1',
children:[
{
title:'菜單1-1',
children:[
{title:'菜單1-1-1'},
{title:'菜單1-1-2'},
{title:'菜單1-1-3'}
]
},
{title:'菜單1-2'},
{title:'菜單1-3'}
]
},
{title:'菜單2'},
{title:'菜單3'}
]
複製代碼
Menu.vuebash
首先咱們來寫個menu組件,這裏放個ul列表,裏面的內容,用插槽來表示。
<template>
<ul>
<slot></slot>
</ul>
</template>
<script>
export default {
name: "Menu"
}
</script>
複製代碼
MenuItem.vue架構
若是沒有子節點,所要展現的標題
<template>
<li><slot></slot></li>
</template>
<script>
export default {
name: "MenuItem"
}
</script>
複製代碼
SubMenu.vueapp
<template>
<div>
<div class="title" @click="change">
<slot name="title"></slot>
<!--name='title'區分插槽 -->
</div>
<div class="sub" v-show="flag">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: "SubMenu",
data(){
return {flag:false}
},
methods:{
change(){
this.flag=!this.flag
}
}
}
</script>
<style>
.sub{
padding-left:20px;
}
</style>
複製代碼
這裏到了咱們實現樹形結構思想的重點,即遞歸組件。當咱們重複判斷有沒有子節點,並作出相應的展現的時候,這裏就可使用遞歸組件了。方便快捷,你值得擁有。ui
因爲有子節點會循環SubMenu這部分操做,因此單獨提出來放到ReSubMenu組件中
<template>
<SubMenu>
<template #title><!--#title爲了標識區分插槽-->
{{data.title}}
</template>
<template v-for="child in data.children">
<MenuItem :key="child.title" v-if="!child.children">{{child.title}}</MenuItem>
<!--ReSubMenu跟name的名字保持一致,至關於循環使用該組件-->
<ReSubMenu v-else :key="child.title" :data="child"></ReSubMenu>
</template>
</SubMenu>
</template>
<script>
import SubMenu from './SubMenu'
import MenuItem from './MenuItem'
export default {
name: "ReSubMenu",//可使用遞歸組件
props:{
data:{
type:Object,//屬性校驗,爲對象數據類型,而且若是沒有賦值,默認給一個空對象
default:()=>({})
}
},
components:{
SubMenu,
MenuItem
}
}
</script>
複製代碼
<div id="app">
<Menu>
<template v-for="menu in menuList">
<MenuItem :key="menu.title" v-if="!menu.children">{{menu.title}}</MenuItem>
<!--這部分是若是有孩子節點則會循環這部分操做,因此要單獨提取出來-->
<!-- <SubMenu v-else>
<template #title>{{menu.title}}</template>
<template v-for="child in menu.children">
<MenuItem>{{child.title}}</MenuItem>
</template>
</SubMenu>-->
<ReSubMenu :key="menu.title" v-else :data="menu"></ReSubMenu>
</template>
</Menu>
<div>
<script>
import Menu from './Menu'
import MenuItem from './MenuItem'
// import SubMenu from './SubMenu'
import ReSubMenu from './ReSubMenu'
export default {
data(){
return{
//這裏的數據我就模擬一個了
menuList:[
{
title:'菜單1',
children:[
{
title:'菜單1-1',
children:[
{title:'菜單1-1-1'},
{title:'菜單1-1-2'},
{title:'菜單1-1-3'}
]
},
{title:'菜單1-2'},
{title:'菜單1-3'}
]
},
{title:'菜單2'},
{title:'菜單3'}
]
}
},
components:{
Menu,MenuItem,ReSubMenu
}
}
</script>
複製代碼
注:本節部分語句參考 https://juejin.im/book/5bc844166fb9a05cd676ebca/section/5bfcecc7f265da61682b102a
。this