element ui源碼解析 -- button篇


要看源碼就得從最簡單的開始,button夠簡單的了,就從他開始吧。

安裝依賴后源碼目錄在:node_modules/element-ui/packages中,可以看到這里的文件夾命名是不是很熟悉,就是我們平時寫的組件名,打開任何一個文件夾,都有一個src文件夾和一個index.js,src文件夾放組件,index.js用於注冊組件

下面來看具體的button源碼如何寫的:

分析從三個方面着手:DOM結構,數據屬性,事件

DOM結構:

按鈕的DOM結構很簡單,要顯示成什么樣子就由css樣式及一些自帶的屬性決定了,這些就交給數據屬性來控制

<button></button>

  

數據屬性:

按鈕的樣式,大小,顯示內容,類型等都需要通過數據屬性來控制,這些數據屬性分兩塊:

a、直接引用props

b、引用computed的屬性

直接引用props的數據大家都能理解,為什么還用到computed呢?

這里就涉及到provider/inject,

provider/inject:簡單的來說就是在父組件中通過provider來提供變量,然后在子組件中通過inject來注入變量。注意官方文檔有一句話“向其所有子孫后代注入一個依賴,不論組件層次有多深,並在起上下游關系成立的時間里始終生效”,這樣看來就明顯了,父組件提供的屬性只能在直接子組件中獲取到,孫組件就獲取不到,provide提供的屬性就解決了這個問題。

為什么用到computed?答案就很明顯了,防止全局設置/父組件的屬性,孫組件獲取不到

Vue.use(Element, {
  size: Cookies.get('size') || 'medium' // set element-ui default size
})

  

有了provider/inject,這里配置的size才能全局起作用。

 

事件:

這里涉及到父子組件通信,子組件向父組件發消息可以用emit實現,父組件監聽即可,一般情況下父組件監聽的事件名都是自定義的,這里特殊了點,父組件直接監聽了“click”事件,誰讓button通常就一個點擊事件呢

 

index.js:

js的作用很簡單,注冊組件並導出

 

最后:

源碼DOM結構上有這樣一句:

<span v-if="$slots.default"><slot></slot></span>

 

我們知道插槽有具名插槽和不具名插槽,“$slots.default”指代的就是不具名插槽。為什么要這么寫,而不是:

<span><slot></slot></span>

  

這里其實是一個很細心的點,如果<el-button></el-button>不寫內容,將會少一個span節點,渲染后的DOM是這樣的

<button data-v-06af20c4="" type="button" class="el-button el-button--default el-button--medium"></button>

  

如果去掉v-if="$slots.default",渲染后將是這樣的

<button data-v-06af20c4="" type="button" class="el-button el-button--default el-button--medium"><span></span></button>

  

 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

除了學知識,我們還可以從源碼中學到一點規范:

:class="[
      type ? 'el-button--' + type : '',
      buttonSize ? 'el-button--' + buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }

  

綁定的class做了歸類,boolean類型的歸為了一類,放到對象中,我們是不是也可以這樣寫,讓代碼更整齊呢


免責聲明!

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



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