前言
之前在這篇文章 基于.NetCore開發部落格項目 StarBlog - (8) 分類層級結構展示 中說到,我為了讓文章分類清單支援層級結構,用了一個樹形元件,不過這個元件太老了,使用的Bootstrap版本居然是3.x的,但又找不到更好的,隻能硬着頭皮用。
但實際效果有很多我不滿意的,感謝開源,我直接fork一份代碼來魔改,實作了我要的效果~
然後還上傳了npm~(第一次在npm上發包)
有需要的同學可以install試試:
npm i bootstrap5-treeview
效果
先放圖,後面再來說改了啥
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL5YDOwIDN1QzMtgzMzIDN3EzMycjM1AjMyAjMtIDN5YjN48CX1AjMyAjMvwlM0kjN2gzLcd2bsJ2Lc12bj5ycn9Gbi52YuIjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
布局修改
我注意到原版對tag的處理是包裝成一個
badge
直接放在文字後面,不知道是不是Bootstrap改了,在目前的5.x版本上看起來擠在一起,而且也沒有顔色,因為原版作者隻加了
badge
一個
class
。
我直接在js代碼裡找到這個badge的定義,修改!
Tree.prototype.template = {
// ...
badge: '<span class="ms-1 badge bg-primary rounded-pill"></span>'
};
加上了背景色和圓角,效果就好看多了~
然後!擠在一起的問題還沒解決,原本的實作渲染出來大概這樣的HTML
<ul class="list-group">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">A fourth item</li>
<li class="list-group-item">And a fifth one</li>
</ul>
理想情況下是兩邊分布,用flex布局正好實作,渲染出來應該類似這樣
<ol class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div>Subheading</div>
<span class="badge bg-primary rounded-pill">tag</span>
</li>
</ol>
但原本這個元件是把所有元素一個個append到
list-group-item
裡面,就導緻出來的效果不美觀
沒事,代碼在手,改!
首先重新定義幾個元素模闆
包括上面的badge也在裡面,所有元素模闆在這
Tree.prototype.template = {
list: '<ul class="list-group"></ul>',
itemWrapper: '<li class="list-group-item d-flex justify-content-between align-items-start"></li>',
itemLeftElem: '<div class="w-100"></div>',
itemRightElem: '<div></div>',
indent: '<span class="mx-2"></span>',
icon: '<span class="icon"></span>',
link: '<a class="w-75" href="#" style="display:inline-block; color:inherit; text-decoration:none;"></a>',
badge: '<span class="ms-1 badge bg-primary rounded-pill"></span>'
};
然後找到組裝清單元素項的代碼
在
Tree.prototype.buildTree
這裡,裡面有個
$.each(nodes, function addNodes(id, node)
循環體
直接改代碼
// 最外層包裝
let treeItem = $(_this.template.itemWrapper)
.addClass('node-' + _this.elementId)
.addClass(node.state.checked ? 'node-checked' : '')
.addClass(node.state.disabled ? 'node-disabled' : '')
.addClass(node.state.selected ? 'node-selected' : '')
.addClass(node.searchResult ? 'search-result' : '')
.attr('data-nodeid', node.nodeId)
.attr('style', _this.buildStyleOverride(node));
// item 内分成兩個元素,用flex布局分布在左右兩邊
let treeItemLeft = $(_this.template.itemLeftElem)
let treeItemRight = $(_this.template.itemRightElem)
treeItem.append(treeItemLeft)
treeItem.append(treeItemRight)
然後把tag渲染代碼改成這樣
// Add tags as badges
if (_this.options.showTags && node.tags) {
$.each(node.tags, function addTag(id, tag) {
treeItemRight.append(
$(_this.template.badge).append(tag)
);
});
}
其他元素全都append到
treeItemLeft
元素下
增加縮進控制
原版沒辦法控制是否開啟子菜單縮進,預設是開啟,我給加了個選項控制開啟
_default.settings = {
// ...
enableIndent: true, // 添加了控制是否啟用縮進的開關
}
然後依然是在上面的那個
$.each(nodes, function addNodes(id, node)
循環裡,加個判斷就搞定了
// Add indent/spacer to mimic tree structure
// 添加了控制是否啟用縮進的開關
if (_this.options.enableIndent) {
for (let i = 0; i < (level - 1); i++) {
treeItemLeft.append(_this.template.indent);
}
}
上傳NPM
第一次在NPM上發包,(也算是為開源社群做貢獻了)
參考了這篇文章:https://segmentfault.com/a/1190000013940567
首先在NPM官網注冊一個賬号,然後本地使用
npm login
登入
完事了在項目的根目錄下執行:
npm publish
就好了
當然我這個是fork的,要把
package.json
裡的資訊改一下,不然會和原作者的包沖突沒法上傳。
小結
魔改前端元件和在NPM發包這的門檻真的是很低,讓我想起了之前在pip上發python包的經曆,也是類似的操作,一鍵送出,直接起飛~
不過相比之下,NPM甚至比pip還更容易一點,至少沒遇到什麼障礙,也不需要額外安裝什麼就完成了
(唯一的障礙是這個包的依賴太老,grunt的上古版本我安不上,後面裝了新版才可以執行任務)
代碼
完整代碼在github:https://github.com/Deali-Axy/bootstrap5-treeview
然後NPM位址:https://www.npmjs.com/package/bootstrap5-treeview
有需要實作樹形結構的同學可以試試,感覺還行~
微信公衆号:「程式設計實驗室」
專注于網際網路熱門新技術探索與團隊靈活開發實踐,包括架構設計、機器學習與資料分析算法、移動端開發、Linux、Web前後端開發等,歡迎一起探讨技術,分享學習實踐經驗。