快速實現(xiàn)一個簡單可復(fù)用可擴展的Vue樹組件

一、樹形數(shù)據(jù)結(jié)構(gòu)
[{id: '1',title: '節(jié)點1'children: [{id: '1-1',title: '節(jié)點1-1'},{id: '1-2',title: '節(jié)點1-2'}]},{id: '2',title: '節(jié)點2',children: [{id: '2-1',title: '節(jié)點2-1'},{id: '2-2',title: '節(jié)點2-2'}]},{id: '3',title: '節(jié)點3'}]
二、Vue樹組件實現(xiàn)的兩個重要屬性
1、組件的name屬性
允許組件模板遞歸地調(diào)用自身。注意,組件在全局用?Vue.component()?注冊時,全局 ID 自動作為組件的 name。
指定?name?選項的另一個好處是便于調(diào)試。有名字的組件有更友好的警告信息。另外,當(dāng)在有 vue-devtools,未命名組件將顯示成?
,這很沒有語義。通過提供?name?選項,可以獲得更有語義信息的組件樹。
2、插槽
Vue插槽借鑒于Web components,是在父組件自定義實現(xiàn)子組件部分dom的一個方法,這大大提高了子組件的復(fù)用性和擴展性。
下面是一個簡單的插槽使用例子。
子組件:
子組件
父組件通過插槽插入的內(nèi)容——具名插槽父組件通過默認(rèn)插槽插入的內(nèi)容——默認(rèn)插槽

1)、作用域插槽
子組件:
子組件
子組件傳到插槽的nodeData的title:{{ someProp.nodeData.title }}
2)、插槽函數(shù)

三、樹組件渲染的實現(xiàn)
1、樹組件調(diào)用形式
作為一個可復(fù)用的樹節(jié)點,渲染出來的樹結(jié)構(gòu)應(yīng)該是可以自定義的,同時對于傳入組件的prop盡可能簡單。
這里設(shè)計的prop僅傳入一個樹形數(shù)據(jù)treeData,對于每一個節(jié)點,使用作用域插槽提供每一個節(jié)點的數(shù)據(jù)來調(diào)用者自定義渲染。所以組件調(diào)用形式很簡單:
{{ nodeData.title }}
2、樹組件代碼實現(xiàn)
樹節(jié)點渲染組件,該組件通過歸調(diào)用自身渲染一個子樹,一直遞歸到渲染完全部葉子節(jié)點。
供外部調(diào)用的樹形組件,提供一些外部調(diào)用的接口
class="tree-node-children":style="{paddingLeft: indent}"v-if="nextShow">v-for="(child, idx) of nodeData.children":nodeData="child":indent="indent":key="idx">
v-for="(nodeData, idx) of treeData":nodeData="nodeData":key="idx">.tree-containertext-align left
樹組件的componentMap保存了所有后代組件的引用。這樣好處在于:在使用tree組件的時候,我們直接訪問的只有樹組件,想直接調(diào)用葉子節(jié)點的相關(guān)方法,可以通過樹組件做轉(zhuǎn)發(fā)。比如想讓id為1的節(jié)點折疊起后代元素,可以調(diào)用this.$refs.tree.showChildren(1, true),在樹組件的showChildren函數(shù)內(nèi),取出對應(yīng)的節(jié)點組件,調(diào)用節(jié)點組件的方法。
節(jié)點自身內(nèi)容的渲染。節(jié)點組件的tree樹形保存了樹組件的引用,節(jié)點自身內(nèi)容的渲染,使用了一個子組件node-content。而node-content的內(nèi)容,來自于樹組件的插槽,我們通過前面所描述函數(shù)形式訪問到樹組件的插槽,調(diào)用函數(shù)得到了虛擬DOM,作為組件node-content的內(nèi)容。當(dāng)然如果未提供插槽,node-content的內(nèi)容會是一段提醒含義的html串,提醒使用者插入插槽(你也可以修改為一個默認(rèn)的渲染,比如渲染出nodeData.title)。
在提供的作用域插槽中,node-content組件向該插槽傳遞了parentData(上級節(jié)點數(shù)據(jù)), data(本級節(jié)點數(shù)據(jù)), level(層級)等一些可能常用的屬性。

