從源碼看Element UI Table組件實現思路

在你實現一個組件過程當中,必定要注意一下幾點html

  • 將代碼模塊化而且分離。若是你將大量的邏輯或者是代碼都放在鉤子函數中(好比mounted),那麼寫出來的組件代碼將很是醜陋,這樣子寫出的代碼也每每難以維護。vue

  • 第二就是要注意可擴展性。由於定製一個基礎組件,也許當你往後還想對它的功能進行擴展的話,那麼必定要注意本身代碼的編寫結構。
    接下來來看一下element ui是如何編寫一個table組件的,在看源碼以前,首先仍是要對他的table組件的大體功能有一個瞭解,這樣咱們在看源碼的時候纔會知道這一段大概實現了什麼功能。git

點開table的src目錄下,有這麼幾個文件github

  • dropdown.jsantd

  • filter-panel.vue(實現表格勾選的組件)app

  • table-body.js (實現表格body的組件)dom

  • table-column.js (實現表中中每一列的組件)模塊化

  • table-footer.js (定義表格尾部的組件,會有一些合計的功能)函數

  • table-header.js(定義表格thead的文件)工具

  • table-layout.js (定義表格佈局的文件)

  • table-store.js(定義事件的方法集中在這裏)

  • table.vue(最終將上述組件整合後的一個最終table組件)

  • util.js(定義了一些工具函數)
    對於這個結構也就是像一開始提到的那樣,將代碼儘可能拆分,這樣組織下來結構清晰。分析的時候我將舉例每一種狀況的表明,相似的照着實現就能夠了。

首先是事件的實現

以row-click爲例,咱們使用這個事件的方式是@row-click=「dosomething」,那組件內部如何觸發這個事件呢,最簡單的方法就是在每一次tr循環的時候都去綁定上一個@click事件就好,在這個事件裏面去emit(‘row-click’)事件就好,但是這就是會有一個問題,事件一多,代碼都集中在methods中,會寫出很是長的代碼,這個時候就須要分離,咱們新建一個store.js,用來管理各類事件。大體實現以下:

const TableStore = function (table,initialSatate) {
  this.table = table
  this.states = {}
}
TableStore.prototype.mutations = {
  handleRowClick () {
    this.table.emit('row-click')
  }
}
Table.prototype.commit = function (name,..agrs){
  mutations[name].apply(name,args)
}

咱們在表格table建立一開始,在data (){}中就會建立一個新的tableStore對象,咱們在每一行點擊的時候只用this.store.commit('handleRowClick');基於這個流程,若是之後還須要繼續添加事件,你就能夠在mutations裏面去定義。

layout.js也是同樣的道理,這裏我只是對錶格的高度去進行了設定,對於一個vue對象來講,不能用dom思路去實現它的高度,我是將vue對象打印出來,在一步一步尋找那個style屬性

TableColumn的實現

其實對於一個表格來講,他的表頭將會很重要。在螞蟻金服的那個antd組件庫中,他們對於表頭的定義是這樣的,你須要傳入一個columns(props),裏面將你定義的每一列信息寫進去,而vue在實現的過程當中,是將做爲

組件children元素,在組件裏再去定義每一列的屬性,基於這兩種實現方式的不一樣,我以爲很大程度上是由於vue中有一個標籤(也多是別的緣由),可是又有一個問題,就是在table-header/table-body/table-column中,他們都是用的render方法去渲染組件,我在參考他們官方編寫的過程當中,用到了jsx語法的模式,不是很理解爲何又採用這種方式去編寫組件。
最後我實現的table功能文檔
以及最終的一個樣例demo

相關文章
相關標籤/搜索