天天看點

魔改了一下bootstrap-treeview元件,釋出個NPM包體驗一下

前言

之前在這篇文章 基于.NetCore開發部落格項目 StarBlog - (8) 分類層級結構展示 中說到,我為了讓文章分類清單支援層級結構,用了一個樹形元件,不過這個元件太老了,使用的Bootstrap版本居然是3.x的,但又找不到更好的,隻能硬着頭皮用。

但實際效果有很多我不滿意的,感謝開源,我直接fork一份代碼來魔改,實作了我要的效果~

然後還上傳了npm~(第一次在npm上發包)

有需要的同學可以install試試:

npm i bootstrap5-treeview
           

效果

先放圖,後面再來說改了啥

魔改了一下bootstrap-treeview元件,釋出個NPM包體驗一下

布局修改

我注意到原版對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前後端開發等,歡迎一起探讨技術,分享學習實踐經驗。