Vue實(shí)現(xiàn)封裝樹狀圖的示例代碼
封裝準(zhǔn)備 完整代碼可直接置底查看
組件的封裝來源于數(shù)據(jù)
我們把樹狀圖(下文統(tǒng)稱為“圖”)的每一個(gè)節(jié)點(diǎn)作為一個(gè)看作一個(gè)對(duì)象,它將需要的節(jié)點(diǎn)屬性如下:
屬性名稱 | 作用 |
---|---|
id | 唯一標(biāo)識(shí) |
title | 節(jié)點(diǎn)名稱 |
children | 子集 |
expend | 展開控制變量 |
//數(shù)據(jù)準(zhǔn)備 let treeData = [ { id: 'treeRoot', title: '目錄根節(jié)點(diǎn)', expend: false, children: [ { id: 'subNode', title: '目錄子節(jié)點(diǎn)', } ], }, ];
開始封裝
我們確認(rèn)了圖的數(shù)據(jù)是一個(gè)可以無限遞歸的層級(jí)數(shù)據(jù),所以我們首先需要封裝一個(gè)方法來遍歷數(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é)點(diǎn)', expend: false, children: [ { id: 'subNode', title: '目錄子節(jié)點(diǎn)', }, ], }, ], }, }, }; </script>
視圖效果
接下來我們?yōu)槊恳患?jí)節(jié)點(diǎn)添加縮進(jìn),我們定義一個(gè)初始值pad,當(dāng)用戶調(diào)用時(shí)未傳pad,此時(shí)采用默認(rèn)值,pad為0,接下來每一級(jí)逐級(jí)+1傳遞,即可實(shí)現(xiàn)節(jié)點(diǎn)縮進(jìn)效果。
<Tree :treeData="item.children" :pad="pad+1">
pad: { type: Number, default: 0, },
當(dāng)數(shù)據(jù)多出之后,我們需要為圖添加展開/收起功能,用expend控制Tree 展示隱藏即可
<Tree :treeData='item.children' v-if="item.expend" :pad="pad+1">
我們可以添加一些圖標(biāo)或者標(biāo)簽來當(dāng)作操作按鈕,這里不予多做解釋。至于不定高度的展開收起動(dòng)畫,我采用grid的template-rows:1fr/0fr;來實(shí)現(xiàn)動(dòng)畫的高度變化。
.tree-sub { display: grid; transition: all 0.3s; } .tree-item-expend { grid-template-rows: 1fr; } .tree-item-hidden { grid-template-rows: 0fr; }
此后,樹狀圖的已具有初步效果,我們還需要再繼續(xù)進(jìn)行一些細(xì)微之處的修改。各位同學(xué)可以通過CV查看具體效果或繼續(xù)進(jìn)行封裝修改。
完整代碼
<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é)點(diǎn)', expend: false, children: [ { id: 'subNode1', title: '目錄子節(jié)點(diǎn)1', expend: false, children: [ { id: 'subNode11', title: '目錄子節(jié)點(diǎn)1-1', }, { id: 'subNode12', title: '目錄子節(jié)點(diǎn)1-2', }, { id: 'subNode13', title: '目錄子節(jié)點(diǎn)1-3', }, { id: 'subNode14', title: '目錄子節(jié)點(diǎn)1-4', }, ], }, { id: 'subNode2', title: '目錄子節(jié)點(diǎn)2', }, { id: 'subNode3', title: '目錄子節(jié)點(diǎn)3', }, { id: 'subNode4', title: '目錄子節(jié)點(diǎn)4', }, { id: 'subNode5', title: '目錄子節(jié)點(diǎn)5', }, { id: 'subNode6', title: '目錄子節(jié)點(diǎn)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>
組件封裝為系列作品,樹狀圖組件遠(yuǎn)遠(yuǎn)不止于此,開發(fā)還有特定需求,如關(guān)鍵字檢索,目錄檢索,多選,單選,懶加載,標(biāo)題超長(zhǎng)縮略提示等。
到此這篇關(guān)于Vue實(shí)現(xiàn)封裝樹狀圖的示例代碼的文章就介紹到這了,更多相關(guān)Vue封裝樹狀圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue 數(shù)據(jù)遍歷篩選 過濾 排序的應(yīng)用操作
這篇文章主要介紹了vue 數(shù)據(jù)遍歷篩選 過濾 排序的應(yīng)用操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11vite+vue3項(xiàng)目初始化搭建的實(shí)現(xiàn)步驟
本文主要介紹了vite+vue3項(xiàng)目初始化搭建的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07vue封裝自定義指令之動(dòng)態(tài)顯示title操作(溢出顯示,不溢出不顯示)
這篇文章主要介紹了vue封裝自定義指令之動(dòng)態(tài)顯示title操作(溢出顯示,不溢出不顯示),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11vue中的任務(wù)隊(duì)列和異步更新策略(任務(wù)隊(duì)列,微任務(wù),宏任務(wù))
這篇文章主要介紹了vue中的任務(wù)隊(duì)列和異步更新策略(任務(wù)隊(duì)列,微任務(wù),宏任務(wù)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08vue3.0 CLI - 2.3 - 組件 home.vue 中學(xué)習(xí)指令和綁定
這篇文章主要介紹了vue3.0 CLI - 2.3 - 組件 home.vue 中學(xué)習(xí)指令和綁定的相關(guān)知識(shí),本文通過實(shí)例代碼相結(jié)合的形式給大家介紹的非常詳細(xì) ,需要的朋友可以參考下2018-09-09