作者:Huup_We
連結:https://juejin.cn/post/6917771825808146446
前端開發的同學們或許會遇到這樣的問題:産品中需要實作某項功能,常用的
elementui
、
antd
等元件庫中确實有差不多功能的元件。但實際上這些元件可能并不能滿足你的功能,或多或少都需要你去看看如何修改它才能滿足你的需求。比如我曾遇到過
element-ui
中的「樹形控件」暴露出的參數沒有我需要的(擷取參數);或者是「對話框」元件我需要給它的
body
加上上下兩條
border
等(樣式修改);還有「級聯選擇器」的多選可搜尋功能:需要修改級聯看闆使它保持展開,且當子節點全部選中時,不展示全部子節點
tag
而隻展示它的父節點
tag
(源碼無此功能)。例如,我需要的功能是左二(因為我不想選項過多時
tag
占得位置太大),而原元件如左一。我截了兩張圖對比:
關于元件庫可能要修改的地方,我将它們分為以下五類可供參考:
- 樣式問題
- 元件暴露的參數和方法不充分(源碼中存在)
- 可利用部分功能,其餘功能要自己開發封裝
-
個元件之間的關聯,多合一2+
- 完全沒有符合的元件
下面詳細說說這些問題,以及如何解決這些問題。如果有不滿足或更好的建議,歡迎指出。
1、元件樣式問題
當修改單個檔案的樣式時,以
less
為例,如果你想要修改元件的樣式,可以使用
/deep/
或
>>>
來深度選擇到你要修改的樣式(這能夠幫你省去一大串的類名)。
如果你要修改全局的樣式,第一種方法,你可以在全局樣式檔案中寫樣式覆寫,引入到
main.js
中即可全局生效。如下:
第二,跟着元件庫提供的『自定義主題』教程修改,一般元件庫都會給出相關的教程。
2、元件暴露的參數和方法不充分
首先提出一個問題,你如何知道元件暴露的參數和方法不充分?其實答案很簡單:因為我看了元件庫的源碼。當我們想要擷取元件的一個參數,首先是看文檔中提供了哪些
Attributes
、
Events
、
Methods
。如果符合需求,直接拿來用就好。如果沒有你要的屬性和方法,請你先去看看源碼中提供了哪些東西沒有向外暴露出來的,但是我們能拿來用的。舉個 ?,上述的「Cascader 級聯選擇器」,我想要在選中一個搜尋的選項後不關閉看闆。我在元件的
Events
、
Methods
中沒有找到相關的方法控制看闆展開,如下:
但當我去
github
上看該元件的源碼時,我發現
toggleDropDownVisible()
方法是控制看闆展開的。于是我在外部用
$refs
直接調用元件裡的這個方法就好了。
具體調用方法如下,這樣即使方法沒有暴露出來,也可以調用它内部的方法:
ref="cascader" // ref擷取元件
placeholder="試試搜尋:指南"
:options="options"
:props="{ multiple: true }"
filterable></el-cascader
@visible-change="$refs.cascader.toggleDropDownVisible(true)"> // 調用元件及其方法
3、可利用部分功能,其餘功能要自己開發封裝
第三類其實我們用到的已經比較少了,畢竟現在的元件庫已經非常豐富了。但是這一步引起的思考确是很重要的,多看别人的源碼有助于提高自己封裝元件的水準。當要用到一個元件,但從頭開發這個元件既複雜又耗時,而元件庫中這個元件需要再往上加一些功能就能為你所用時,你可以考慮把元件庫的代碼拿到自己本地,修改它。第一步你需要将元件代碼浏覽一遍,了解它的邏輯。看看你需要加什麼代碼,如果在
vue
中,使用
computed
、
watch
,或是修改
created
、
mounted
、
methods
就能完成你的功能,那麼就大膽地嘗試。舉個 ? 在
element-ui
中,它提供的多選可搜尋級聯元件有一個問題:當使用者選中全部子節點時不會合并為顯示父節點。要想完成這個功能,在經曆過上述步驟一番探索後發現還是要修改源碼才能完成。于是我基于原本多選可搜尋的級聯選擇器,進行以下優化:
- 預設看到級聯看闆展開,不會收起
- 搜尋選中後展示級聯看闆,并勾選搜尋選中的節點
- 當子級節點全部選中後,tag 隻展示一個父級節點,而不是全部子節點
- 删除節點
由于我修改了
tag
的展示,是以它的
deleteTag
事件也要重寫。
其實修改元件庫代碼的過程并不難,主要是看懂它的邏輯,以及其中哪些東西是你可以用的。上述元件的源碼可以在 GitHub[1] 檢視。
4、 2+
個元件之間的關聯,多合一
2+
到這一步,其實你已經翻越最難的大山了!而這裡要說的多個元件之間的關聯其實已經處于優化使用者體驗的道路上了。思考一下,什麼時候會用到多個元件之間的關聯呢?其實場景有很多,例如将「Form 表單」、「Table 表格」和「Pagination 分頁」結合起來,封裝成一個元件,這樣在多表格的項目中直接使用就好了;将
table
和
pagination
放到一個元件中:
"pug">
div
.el-table
template(v-for="(item, index) in columns")
el-table-column(
:prop="item.prop"
:key="index"
:label="item.label")
el-pagination.pg-wrapper(
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pagesize"
:total="total")
</template>
需要傳入的參數如下:列資訊
columns
、單頁資料量
pagesize
、目前頁碼
currentPage
、表格資料
tableData
、資料總數
total
、表單查詢的參數
query
等。
使用時我們隻需要傳以上的參數就可以直接調用這兩個元件了。還有「表格中行選中狀态資料」,與「展示資料」之間的關聯等等,可發揮之處有很多。将他們封裝後可以大大減輕重複的工作量,特别是像背景管理類的項目,頁面間相似度很高的,尤其适合這種方法。
5、完全沒有符合的元件
如果你要的元件,外部的元件庫中都沒有提供,那就自己動手封裝一個。盡可能将你的元件變得通用,相容。嘗試想一想你的元件是否在其他情況下也能用。另外也可以多看看别人是如何封裝元件的,這有助于你自己開發。如果你可以将你在前端開發道路上自己封裝的元件一個個收集起來,大機率可以友善你以後相同場景下直接複用,也有助于你的代碼解耦。
總結
如果你遇到了元件庫中的元件不合适的,先考慮看看是否能利用它的方法或屬性達到效果,再看看能否修改它的代碼達成目的。如果最後實在不行,那麼就自己動手造輪子吧!自己造的輪子記得記下來,沒準以後就能用上!最後,Vue Demo Collection[2] 這個項目,是我在開發過程中遇到的通用
Vue
元件的
demo
收集,包含了
Vue/CSS/Echarts
等一些可以複用的元件 ❤️,基本上我認為可以複用的元件和代碼片段我都會記錄在這,友善自己的回顧和使用,也算是個人成長的記錄。
參考資料
[1]
GitHub: https://github.com/Gesj-yean/vue-demo-collection/tree/master/docs/.vuepress/components/cascader
[2]
Vue Demo Collection: https://github.com/Gesj-yean/vue-demo-collection
交流讨論
歡迎關注公衆号「前端試煉」,公衆号平時會分享一些實用或者有意思的東西,發現代碼之美。專注深度和最佳實踐,希望打造一個高品質的公衆号。
公衆号背景回複「小煉」加我微信,帶你飛。
如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~