Vue實現(xiàn)封裝樹狀圖的示例代碼
封裝準備 完整代碼可直接置底查看
組件的封裝來源于數(shù)據(jù)
我們把樹狀圖(下文統(tǒng)稱為“圖”)的每一個節(jié)點作為一個看作一個對象,它將需要的節(jié)點屬性如下:
| 屬性名稱 | 作用 |
|---|---|
| id | 唯一標識 |
| title | 節(jié)點名稱 |
| children | 子集 |
| expend | 展開控制變量 |
//數(shù)據(jù)準備
let treeData = [
{
id: 'treeRoot',
title: '目錄根節(jié)點',
expend: false,
children: [
{
id: 'subNode',
title: '目錄子節(jié)點',
}
],
},
];
開始封裝
我們確認了圖的數(shù)據(jù)是一個可以無限遞歸的層級數(shù)據(jù),所以我們首先需要封裝一個方法來遍歷數(shù)據(jù)。
//樹狀圖數(shù)據(jù)遍歷方法
function TreeNode(arr) {
return arr.reduce((pre, cur) => {
if (cur.children && Array.isArray(cur.children)) {
cur.children = TreeNode(cur.children);
}
pre.push(cur);
return pre;
}, []);
}
其次是組件內(nèi)部結(jié)構(gòu),我們需要用到遞歸組件,所謂的遞歸組件就是在vue單文件內(nèi)部給予name屬性,我們就可以在該文件內(nèi)直接調(diào)用組件。
<template>
<div class="tree">
<div class="tree-item" v-for="item in treeData" :key="item.id">
<div>{{ item.title }}</div>
<Tree :treeData="item.children || []" />
</div>
</div>
</template>
<script>
export default {
name: 'Tree',
props: {
treeData: {
default: [
{
id: 'treeRoot',
title: '目錄根節(jié)點',
expend: false,
children: [
{
id: 'subNode',
title: '目錄子節(jié)點',
},
],
},
],
},
},
};
</script>
視圖效果

接下來我們?yōu)槊恳患壒?jié)點添加縮進,我們定義一個初始值pad,當用戶調(diào)用時未傳pad,此時采用默認值,pad為0,接下來每一級逐級+1傳遞,即可實現(xiàn)節(jié)點縮進效果。
<Tree :treeData="item.children" :pad="pad+1">
pad: {
type: Number,
default: 0,
},
當數(shù)據(jù)多出之后,我們需要為圖添加展開/收起功能,用expend控制Tree 展示隱藏即可
<Tree :treeData='item.children' v-if="item.expend" :pad="pad+1">
我們可以添加一些圖標或者標簽來當作操作按鈕,這里不予多做解釋。至于不定高度的展開收起動畫,我采用grid的template-rows:1fr/0fr;來實現(xiàn)動畫的高度變化。
.tree-sub {
display: grid;
transition: all 0.3s;
}
.tree-item-expend {
grid-template-rows: 1fr;
}
.tree-item-hidden {
grid-template-rows: 0fr;
}
此后,樹狀圖的已具有初步效果,我們還需要再繼續(xù)進行一些細微之處的修改。各位同學(xué)可以通過CV查看具體效果或繼續(xù)進行封裝修改。
完整代碼
<template>
<div class="tree">
<div class="tree-item" v-for="item in treeData" :key="item.id">
<div class="tree-item-row" :style="`padding-left:${pad}rem`">
<div class="tree-item-row-opr" @click.stop="item.expend = !item.expend" v-if="item.children && Array.isArray(item.children)">
{{ item.expend ? '-' : '+' }}
</div>
<div class="tree-item-row-opr-none" v-else></div>
<div class="tree-item-row-text">{{ item.title }}</div>
</div>
<div
class="tree-sub"
:class="{
'tree-item-expend': item.expend,
'tree-item-hidden': !item.expend,
}"
>
<Tree :treeData="item.children || []" :pad="pad + 1" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Tree',
props: {
treeData: {
Type: Array,
default: () => [
{
id: 'treeRoot',
title: '目錄根節(jié)點',
expend: false,
children: [
{
id: 'subNode1',
title: '目錄子節(jié)點1',
expend: false,
children: [
{
id: 'subNode11',
title: '目錄子節(jié)點1-1',
},
{
id: 'subNode12',
title: '目錄子節(jié)點1-2',
},
{
id: 'subNode13',
title: '目錄子節(jié)點1-3',
},
{
id: 'subNode14',
title: '目錄子節(jié)點1-4',
},
],
},
{
id: 'subNode2',
title: '目錄子節(jié)點2',
},
{
id: 'subNode3',
title: '目錄子節(jié)點3',
},
{
id: 'subNode4',
title: '目錄子節(jié)點4',
},
{
id: 'subNode5',
title: '目錄子節(jié)點5',
},
{
id: 'subNode6',
title: '目錄子節(jié)點6',
},
],
},
],
},
pad: {
type: Number,
default: 0,
},
},
};
</script>
<style lang="less">
.tree {
box-sizing: border-box;
overflow: hidden;
&-item {
display: flex;
flex-direction: column;
gap: 4px;
&-row {
display: flex;
gap: 4px;
&-opr {
cursor: pointer;
width: 16px;
font-size: 16px;
height: 20px;
line-height: 20px;
text-align: center;
}
&-opr-none {
cursor: default;
}
}
.tree-sub {
display: grid;
transition: all 0.3s;
}
.tree-item-expend {
grid-template-rows: 1fr;
}
.tree-item-hidden {
grid-template-rows: 0fr;
}
}
}
</style>組件封裝為系列作品,樹狀圖組件遠遠不止于此,開發(fā)還有特定需求,如關(guān)鍵字檢索,目錄檢索,多選,單選,懶加載,標題超長縮略提示等。
到此這篇關(guān)于Vue實現(xiàn)封裝樹狀圖的示例代碼的文章就介紹到這了,更多相關(guān)Vue封裝樹狀圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue elementui簡易側(cè)拉欄的使用小結(jié)
這篇文章主要介紹了vue elementui簡易側(cè)拉欄的使用,增加了側(cè)拉欄,目的是可以選擇多條數(shù)據(jù)展示數(shù)據(jù),本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-06-06
vue中的rules表單校驗規(guī)則使用方法示例詳解 :rules=“rules“
這篇文章主要介紹了vue中的rules表單校驗規(guī)則使用方法示例詳解 :rules=“rules“,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-11-11
完美解決vue中報錯?“TypeError:?Cannot?read?properties?of?null?
這篇文章主要介紹了完美解決vue中報錯?“TypeError:?Cannot?read?properties?of?null?(reading?‘forEach‘)“,本文給大家分享詳細解決方案,需要的朋友可以參考下2023-02-02
Vue使用.sync 實現(xiàn)父子組件的雙向綁定數(shù)據(jù)問題
這篇文章主要介紹了Vue使用.sync 實現(xiàn)父子組件的雙向綁定數(shù)據(jù),需要的朋友可以參考下2019-04-04
一文詳解Vue.js生產(chǎn)環(huán)境文件及優(yōu)化策略
隨著 Vue.js 在前端開發(fā)中的普及,如何高效地將 Vue 項目部署到生產(chǎn)環(huán)境成為了開發(fā)者關(guān)注的重點,本文將詳細解析 Vue.js 生產(chǎn)環(huán)境文件的使用方法、優(yōu)缺點以及優(yōu)化策略,需要的朋友可以參考下2024-12-12

