超詳細 ElementUI 源碼分析 —— Layout

Layout 是用來快速佈局的組件,本質上是和 Bootstrap 的柵格系統(真的很牛批,建議看一下它的源碼)同樣,將每一行分紅 24 個小塊,每個小塊就是一列,經過指定合併的列數來建立佈局,本文就 ElementUI 的 Layout 佈局進行了分析。html

Layout 佈局

首先咱們來分析一下問什麼要使用 Layout?vue

  • 咱們在寫原生 HTML 甚至是在使用 Vue 模板時,會使用div對每一個模塊進行分割,可是通篇的div會使咱們的代碼語義不清,H5 就要求咱們使用標籤語義化,但即使是使用了標籤語義化,有一些地方仍是會顯得模糊不清,並且在樣式上也難以維護。
  • 對於簡單的佈局咱們不但願每次都須要本身來寫,若是有一個模板快速幫咱們實現佈局就行了。

基於以上理由,Layout 就出現了,它能作什麼?git

  • 快速佈局
  • 響應式佈局

這裏就不說使用了,具體使用請參考官方文檔github

Layout 佈局分爲兩個組件:row 和 colide

參數

關於 row 的參數請參考函數

col 參數請參考源碼分析

間隔

關於 row 組件最重要的部分就是柵格間隔gutter,也就是每個分欄之間的距離,看源碼:佈局

computed: {
  style () {
    const ret = {}

    // 若是傳入了 gutter
    if (this.gutter) {
      // 向左移動間隔的一半
      ret.marginLeft = `-${this.gutter / 2}px`
      // 向右移動間隔的一半
      ret.marginRight = ret.marginLeft
      // 
    }

    return ret
  }
}
複製代碼

首先gutter是由每一列自身的padding產生的,在col.js中能夠看出來,paddinggutter的一半。假如間隔爲 20px,列的padding:0 10px,因此兩列之間就產生了 20px 的間隔,這個很好理解。post

那麼row.js中爲何要給 row 組件添加一個margin呢,熟悉 Bootstrap 的小夥伴應該知道,這是考慮了在「列中嵌套行」的狀況,若是在行中不加margin就會致使有某些列的間隔大於預期,好比說下面的代碼結構flex

<el-row :gutter="20" type="flex" justify="end">
  <el-col :span="6">
    <el-row :gutter="10">
      <el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
      <el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
    </el-row>
  </el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
</el-row>
複製代碼

在第一列中嵌套了一行,這一行裏又有兩列,看渲染出來的效果圖:

能夠看出來,外面的大間隔爲 20px,第一列的小間隔爲 10px,如今把margin去了看一下對比:

能夠明顯發現第一大列的左右都增長了 5px,這樣就破壞了原有的gutter值,使得佈局不符合預期,這就是margin的精妙之處。

渲染函數

而後咱們看一下渲染函數。

移步官網查看渲染函數的詳細介紹

// 渲染函數
render (h) {
  return h(
    // 默認渲染的是一個 div
    this.tag,
    {
      // 至關於模板中的 :class
      class: [
        'el-row',
        // 若是 flex 佈局不是默認的值,就會加上 .is-justify-
        // 就是加上了 justify-content: flex-end
        this.justify !== 'start' ? `is-justify-${this.justify}` : '',
        this.align !== 'top' ? `is-align-${this.align}` : '',
        // 若是開啓了 flex 佈局模式,則會加上 .el-row--flex
        // 就是加上了 display: flex
        { 'el-row--flex': this.type === 'flex' }
      ],
      style: this.style
    },
    // 子集虛擬節點
    this.$slots.default
  )
}
複製代碼

咱們注意到 row 組件 和 col 組件中沒有提供模板,而是使用渲染函數來建立的 HTML 結構,這樣作能讓咱們更好的處理細節。

關於col.js裏面的東西主要是爲了添加組件的樣式,經過父組件傳遞的屬性動態添加 class,Layout 佈局主要部分也就是 CSS 了,因此本文先不詳述了,後期會單獨分析樣式文件,感興趣的能夠先關注一波。源碼全部的解釋在個人Github裏,歡迎進來點個 star。

傳送門

【2020.3.15】超詳細 ElementUI 源碼分析 —— Layout

相關文章
相關標籤/搜索