魔改了一下bootstrap-treeview組件,發(fā)布個(gè)NPM包體驗(yàn)一下
前言
之前在這篇文章 基于.NetCore開發(fā)博客項(xiàng)目 StarBlog - (8) 分類層級(jí)結(jié)構(gòu)展示 中說(shuō)到,我為了讓文章分類列表支持層級(jí)結(jié)構(gòu),用了一個(gè)樹形組件,不過(guò)這個(gè)組件太老了,使用的Bootstrap版本居然是3.x的,但又找不到更好的,只能硬著頭皮用。
但實(shí)際效果有很多我不滿意的,感謝開源,我直接fork一份代碼來(lái)魔改,實(shí)現(xiàn)了我要的效果~
然后還上傳了npm~(第一次在npm上發(fā)包)
有需要的同學(xué)可以install試試:
npm?i?bootstrap5-treeview
效果
先放圖,后面再來(lái)說(shuō)改了啥

布局修改
我注意到原版對(duì)tag的處理是包裝成一個(gè)badge直接放在文字后面,不知道是不是Bootstrap改了,在目前的5.x版本上看起來(lái)擠在一起,而且也沒(méi)有顏色,因?yàn)樵孀髡咧患恿?code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(150, 84, 181);">badge一個(gè)class。
我直接在js代碼里找到這個(gè)badge的定義,修改!
Tree.prototype.template?=?{
????//?...
????badge:?''
};
加上了背景色和圓角,效果就好看多了~
然后!擠在一起的問(wèn)題還沒(méi)解決,原本的實(shí)現(xiàn)渲染出來(lái)大概這樣的HTML
<ul?class="list-group">
??<li?class="list-group-item">An?itemli>
??<li?class="list-group-item">A?second?itemli>
??<li?class="list-group-item">A?third?itemli>
??<li?class="list-group-item">A?fourth?itemli>
??<li?class="list-group-item">And?a?fifth?oneli>
ul>
理想情況下是兩邊分布,用flex布局正好實(shí)現(xiàn),渲染出來(lái)應(yīng)該類似這樣
<ol?class="list-group">
??<li?class="list-group-item?d-flex?justify-content-between?align-items-start">
????<div>Subheadingdiv>
????<span?class="badge?bg-primary?rounded-pill">tagspan>
??li>
ol>
但原本這個(gè)組件是把所有元素一個(gè)個(gè)append到list-group-item里面,就導(dǎo)致出來(lái)的效果不美觀
沒(méi)事,代碼在手,改!
首先重新定義幾個(gè)元素模板
包括上面的badge也在里面,所有元素模板在這
Tree.prototype.template?=?{
????list:?'
',
????itemWrapper:?'',
????itemLeftElem:?'',
????itemRightElem:?'',
????indent:?'',
????icon:?'',
????link:?'',
????badge:?''
};
然后找到組裝列表元素項(xiàng)的代碼
在Tree.prototype.buildTree這里,里面有個(gè)$.each(nodes, function addNodes(id, node)循環(huán)體
直接改代碼
//?最外層包裝
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?內(nèi)分成兩個(gè)元素,用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元素下
增加縮進(jìn)控制
原版沒(méi)辦法控制是否開啟子菜單縮進(jìn),默認(rèn)是開啟,我給加了個(gè)選項(xiàng)控制開啟
_default.settings?=?{
????//?...
????enableIndent:?true,?//?添加了控制是否啟用縮進(jìn)的開關(guān)
}
然后依然是在上面的那個(gè)$.each(nodes, function addNodes(id, node)循環(huán)里,加個(gè)判斷就搞定了
//?Add?indent/spacer?to?mimic?tree?structure
//?添加了控制是否啟用縮進(jìn)的開關(guān)
if?(_this.options.enableIndent)?{
????for?(let?i?=?0;?i?(level?-?1);?i++)?{
????????treeItemLeft.append(_this.template.indent);
????}
}
上傳NPM
第一次在NPM上發(fā)包,(也算是為開源社區(qū)做貢獻(xiàn)了)
參考了這篇文章:https://segmentfault.com/a/1190000013940567
首先在NPM官網(wǎng)注冊(cè)一個(gè)賬號(hào),然后本地使用npm login登錄
完事了在項(xiàng)目的根目錄下執(zhí)行:npm publish就好了
當(dāng)然我這個(gè)是fork的,要把package.json里的信息改一下,不然會(huì)和原作者的包沖突沒(méi)法上傳。
小結(jié)
魔改前端組件和在NPM發(fā)包這的門檻真的是很低,讓我想起了之前在pip上發(fā)python包的經(jīng)歷,也是類似的操作,一鍵提交,直接起飛~
不過(guò)相比之下,NPM甚至比pip還更容易一點(diǎn),至少?zèng)]遇到什么障礙,也不需要額外安裝什么就完成了
(唯一的障礙是這個(gè)包的依賴太老,grunt的上古版本我安不上,后面裝了新版才可以執(zhí)行任務(wù))
代碼
完整代碼在github:https://github.com/Deali-Axy/bootstrap5-treeview
然后NPM地址:https://www.npmjs.com/package/bootstrap5-treeview
有需要實(shí)現(xiàn)樹形結(jié)構(gòu)的同學(xué)可以試試,感覺還行~
