來自:掘金,作者:Huup_We
鏈接:https://juejin.cn/post/6917771825808146446
場景
前端開發的同學可能會遇到過這樣的問題: 產品找那個需要實現某項功能,常用的elementui,antd組件庫中確實有差不多功能的組件 但實際上這些組件可能並不能滿足你的功能,或多或少都需要修改才能滿足需求
關於組件庫可能要修改的地方,我將它們分為以下五類可供參考
- 樣式問題
- 組件暴露的參數和方法不充分 但是源碼中存在
- 可利用部分功能 但其余功能需要自己開發封裝
- 兩個及以上的組件之間有聯動
- 完全沒有符合的組件
分析和解決
組件樣式問題
當修改單個文件的樣式時,以 less 為例,如果你想要修改組件的樣式,可以使用 /deep/ 或 >>> 來深度選擇到你要修改的樣式(這能夠幫你省去一大串的類名)
.dialog-wrapper {
/deep/.el-dialog__body{
border: solid 1px #999;
}
}
如果你要修改全局的樣式,第一種方法,你可以在全局樣式文件中寫樣式覆蓋,引入到 main.js 中即可全局生效。如下
import "./assets/css/index.css";
如果是修改antd 可以使用:global(.className)的語法去修改組件庫的樣式
.wrap {
:global(.ant-modal-body) {
padding-top: 0;
& > div {
margin: 0 -24px;
max-height: 680px !important;
}
}
}
組件庫的組件暴露的參數和方法不充分
當我們想要獲取組件的一個參數,首先是看文檔中提供了哪些 Attributes、Events、Methods。如果符合需求,直接拿來用就好。如果沒有你要的屬性和方法,請你先去看看源碼中提供了哪些東西沒有向外暴露出來的,但是我們能拿來用的
以elementui的cascader級聯選擇器舉例,我想要在選中一個搜索的選項后不關閉看板。我在組件的 Events、Methods中沒有找到相關的方法控制看板展開,但當我去 github 上看該組件的源碼時,我發現 toggleDropDownVisible() 方法是控制看板展開的。於是我在外部用 $refs 直接調用組件里的這個方法就好了
el-cascader
ref="cascader" // ref獲取組件
placeholder="試試搜索:指南"
:options="options"
:props="{ multiple: true }"
filterable></el-cascader
@visible-change="$refs.cascader.toggleDropDownVisible(true)"> // 調用組件及其方法
可利用部分功能,其余功能要自己開發封裝
當要用到一個組件,但從頭開發這個組件既復雜又耗時,而組件庫中這個組件需要再往上加一些功能就能為你所用時,你可以考慮把組件庫的代碼拿到自己本地,修改它
兩個及以上的組件之間的聯動
其實場景有很多,例如將「Form 表單」、「Table 表格」和「Pagination 分頁」結合起來,封裝成一個組件,這樣在多表格的項目中直接使用就好了;將 table 和 pagination 放到一個組件中:
<template lang="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 等
props: {
// 列信息
columns: {
type: Array,
default: [],
}
// 單頁數據量
pagesize: {
type: Number,
default: 10,
},
// 當前頁碼
currentPage: {
type: Number,
default: 1,
},
// 表格數據
tableData: {
type: Array,
default: [],
},
// 數據總數
total: {
type: Number,
default: 1000,
},
// 獲取數據的接口
fetch:{
type: function,
default:() => {}
},
// 表單查詢的參數
query:{
type: Object,
default: () => {}
}
},
methods: {
// 改變當前頁碼 currentPage 時觸發
handleCurrentChange: function (currentPage) {
this.$emit('handleChange', this.pagesize, currentPage)
this.fetch(this.query)
},
// 改變當前頁 pageSize 時觸發
handleSizeChange: function (pageSize) {
this.$emit('handleChange', pageSize, this.currentPage)
this.fetch(this.query)
}
}
完全沒有符合的組件
如果你要的組件,外部的組件庫中都沒有提供,那就自己動手封裝一個。盡可能將你的組件變得通用,兼容。嘗試想一想你的組件是否在其他情況下也能用。另外也可以多看看別人是如何封裝組件的,這有助於你自己開發。
如果你可以將你在前端開發道路上自己封裝的組件一個個收集起來,大概率可以方便你以后相同場景下直接復用,也有助於你的代碼解耦