前端如何修改組件庫源碼來封裝符合自己需求的組件


來自:掘金,作者: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)
  }
}

完全沒有符合的組件

如果你要的組件,外部的組件庫中都沒有提供,那就自己動手封裝一個。盡可能將你的組件變得通用,兼容。嘗試想一想你的組件是否在其他情況下也能用。另外也可以多看看別人是如何封裝組件的,這有助於你自己開發。

如果你可以將你在前端開發道路上自己封裝的組件一個個收集起來,大概率可以方便你以后相同場景下直接復用,也有助於你的代碼解耦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM