欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Element-ui?Layout布局(Row和Col組件)的實(shí)現(xiàn)

 更新時間:2021年12月06日 10:12:39   作者:Devin2016  
我們在實(shí)際開發(fā)中遇到一些布局的時候會用到Layout布局,本文就詳細(xì)的介紹了Element-ui?Layout布局(Row和Col組件)的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下

我們在實(shí)際開發(fā)中遇到一些布局的時候會用到Layout布局,這個布局只要配置一些參數(shù)就能夠達(dá)到很好的布局效果甚至可以響應(yīng)式,那里面的具體是怎么實(shí)現(xiàn)的呢,讓我們?nèi)テ书_Element-UI的源碼,學(xué)習(xí)里面的一些細(xì)節(jié)吧。

基本說明以及用法

Element-UI的Layout布局是通過基礎(chǔ)的24分欄,迅速簡便地創(chuàng)建布局。根據(jù)不同的組合,很快的就能夠生成一個很美觀的響應(yīng)式布局。具體的用法如下:

<el-row>
  <el-col :span="24"><div class="grid-content bg-purple-dark"></div></el-col>
</el-row>

由上述的示例代碼可以看出Row組件主要是創(chuàng)建每行分欄的布局方式,比如之間的一些間隔、對齊方式等。而Col則創(chuàng)建每個分欄,分欄的長度、偏移量等。我們可以進(jìn)行自由組合每個分欄,從而達(dá)到一種響應(yīng)式效果。

Row組件的分析

render函數(shù)

我們都知道vue除了可以使用template模板編寫組件外,有時候我們還可以直接使用render函數(shù)去編寫一個組件。因?yàn)閠emplate模板最終也是編譯成了render函數(shù)。
為什么會有render函數(shù)的寫法?比如現(xiàn)在有個需求:根據(jù)動態(tài)的level生成從h1-h6字體大小的標(biāo)題的時候,我們?nèi)绻褂胻emplate去實(shí)現(xiàn)的話我們頁面中可能會出現(xiàn)很多類似這樣的偽代碼:

<template>
   <h1 v-if="level === 1">
    <slot></slot>
  </h1>
  <h2 v-else-if="level === 2">
    <slot></slot>
  </h2>
  <h3 v-else-if="level === 3">
    <slot></slot>
  </h3>
  <h4 v-else-if="level === 4">
    <slot></slot>
  </h4>
  <h5 v-else-if="level === 5">
    <slot></slot>
  </h5>
  <h6 v-else-if="level === 6">
    <slot></slot>
  </h6>
</template>

但是如果是使用render函數(shù)則是比較簡單:

Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // 標(biāo)簽名稱
      this.$slots.default // 子節(jié)點(diǎn)數(shù)組
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

這里還有一個代碼優(yōu)化點(diǎn)是。this.$slots.default存儲的就是插槽內(nèi)容,不需要寫那么多遍。

源碼分析

Row組件的源碼比較簡單,因?yàn)槲覀兛梢酝ㄟ^tag這個prop對其指定一個渲染標(biāo)簽,所以組件是直接使用render渲染函數(shù)進(jìn)行編寫。 render函數(shù)部分如下:

render(h) {
    return h(this.tag, {
      class: [
        'el-row',
        this.justify !== 'start' ? `is-justify-${this.justify}` : '',
        this.align !== 'top' ? `is-align-${this.align}` : '',
        { 'el-row--flex': this.type === 'flex' }
      ],
      style: this.style
    }, this.$slots.default);
  }

如上的源碼可以得出Row主要是控制class名來進(jìn)行控制內(nèi)容布局的。這里有g(shù)utter屬性能夠控制行內(nèi)列的間隔數(shù)。如果說我們設(shè)置為gutter=20,那么每個列項(xiàng)都進(jìn)行左右間距10px,那么就會出現(xiàn)個問題:第一個列項(xiàng)跟最后一個列項(xiàng)會出現(xiàn)左右的間距。那該如何讓第一個跟最后一個左右間隔去掉這個10px呢?Row的處理方案是這個行左右各偏-10px,所以用了一個計算屬性來設(shè)置樣式:

computed: {
    style() {
      const ret = {};
      if (this.gutter) {
        ret.marginLeft = `-${this.gutter / 2}px`;
        ret.marginRight = ret.marginLeft;
      }
      return ret;
    }
  },

Col組件的分析

組件分析

Col主要是為了設(shè)置每一列的長度以及偏移量。主要的屬性是span、offset;同樣這個組件也是采用render函數(shù)去編寫,首先我們看如何通過span、offset去控制列的,源碼如下:

render(h) {
    let classList = [];
    let style = {};
    ...

    ['span', 'offset', 'pull', 'push'].forEach(prop => {
      if (this[prop] || this[prop] === 0) {
        classList.push(
          prop !== 'span'
            ? `el-col-${prop}-${this[prop]}`
            : `el-col-${this[prop]}`
        );
      }
    });

    ...

    return h(this.tag, {
      class: ['el-col', classList],
      style
    }, this.$slots.default);
  }

從這可以看出,col的列寬是通過不同class名去做控制的。我們找到對應(yīng)的.scss文件,發(fā)現(xiàn)他使用了sass@for循環(huán)語句去計算不同格子的寬度:

@for $i from 0 through 24 {
  .el-col-#{$i} {
    width: (1 / 24 * $i * 100) * 1%;
  }

  .el-col-offset-#{$i} {
    margin-left: (1 / 24 * $i * 100) * 1%;
  }

  .el-col-pull-#{$i} {
    position: relative;
    right: (1 / 24 * $i * 100) * 1%;
  }

  .el-col-push-#{$i} {
    position: relative;
    left: (1 / 24 * $i * 100) * 1%;
  }
}

同理offset也是使用相同的邏輯。這樣我們就可以根據(jù)不同的span、跟offset混合組合不同風(fēng)布局了,是不是感覺背后的邏輯是如此的簡單呢。我們再思考一個問題就是如果我們要控制一組相同的列寬間隔,需要一個個的去做設(shè)置么?答案是不用的,我們可以借助上述的Row組件中的gutter屬性去做統(tǒng)一設(shè)置。那怎么實(shí)現(xiàn)的呢?源碼如下:

 computed: {
    gutter() {
      let parent = this.$parent;
      while (parent && parent.$options.componentName !== 'ElRow') {
        parent = parent.$parent;
      }
      return parent ? parent.gutter : 0;
    }
  }

我們通過往上遍歷父組件,如果父組件的組件名為ElRow,則取到gutter值,然后讓組件左右內(nèi)邊距設(shè)置對應(yīng)的值就好了:

if (this.gutter) {
      style.paddingLeft = this.gutter / 2 + 'px';
      style.paddingRight = style.paddingLeft;
    }

這樣我們就解決了統(tǒng)一列寬設(shè)置的問題;

響應(yīng)式布局

這里我們用到了css3中的媒體查詢來進(jìn)行響應(yīng)式布局,相應(yīng)尺寸分別是xs、sm、md、lg 和 xl。使用代碼如下:

<el-row :gutter="10">
  <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"><div class="grid-content bg-purple"></div></el-col>
  <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"><div class="grid-content bg-purple-light"></div></el-col>
  <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"><div class="grid-content bg-purple"></div></el-col>
  <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>

說明:xs:<768px 響應(yīng)式柵格數(shù)或者柵格屬性對象,sm:≥768px 響應(yīng)式柵格數(shù)或者柵格屬性對象,md:≥992px 響應(yīng)式柵格數(shù)或者柵格屬性對象,lg:≥1200px 響應(yīng)式柵格數(shù)或者柵格屬性對象,xl:≥1920px 響應(yīng)式柵格數(shù)或者柵格屬性對象.

背后的邏輯就是不同屏幕尺寸所展示的格子數(shù)是不一樣的,而且是根據(jù)屏幕寬度進(jìn)行響應(yīng)式。首先,我們看是如何進(jìn)行不同的class綁定的:

['xs', 'sm', 'md', 'lg', 'xl'].forEach(size => {
      if (typeof this[size] === 'number') {
        classList.push(`el-col-${size}-${this[size]}`);
      } else if (typeof this[size] === 'object') {
        let props = this[size];
        Object.keys(props).forEach(prop => {
          classList.push(
            prop !== 'span'
              ? `el-col-${size}-${prop}-${props[prop]}`
              : `el-col-${size}-${props[prop]}`
          );
        });
      }
    });

這里面xs等屬性也是可以使用對象。所以會有個處理對象的邏輯;以上的js處理的邏輯比較簡單,我們再看一下css是怎么處理這個媒體查詢的邏輯的。
在分析css的時候,我們先了解一個概念,那就是sass中的內(nèi)置方法map-get。map-get($map,$key)函數(shù)的作用就是可以通過$key取到對應(yīng)的value值,可以理解為就是一個映射關(guān)系。如果不存在則不會編譯對應(yīng)的css。舉個??:

$social-colors: (
    dribble: #ea4c89,
    facebook: #3b5998,
    github: #171515,
    google: #db4437,
    twitter: #55acee
);
.btn-dribble{
  color: map-get($social-colors,facebook);
}
// 編譯后
.btn-dribble {
  color: #3b5998;
}

第二個是sass內(nèi)置方法inspect(value),這個方法就是一個返回一個字符串的表示形式,value是一個sass表達(dá)式。舉個??:

$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;

$--breakpoints: (
  'xs' : (max-width: $--sm - 1),
  'sm' : (min-width: $--sm),
  'md' : (min-width: $--md),
  'lg' : (min-width: $--lg),
  'xl' : (min-width: $--xl)
);
@mixin res($breakpoint){
  $query:map-get($--breakpoints,$breakpoint)
  @if not $query {
    @error 'No value found for `#{$breakpoint}`. Please make sure it is 
    defined in `$breakpoints` map.';
  }
  @media #{inspect($query)}
   {
    @content;
   }
}
.element {
  color: #000;
 
  @include res(sm) {
    color: #333;
  }
}
// 編譯后的css

.element {
  color: #000;
}
@media (min-width: 768px) {
  .element {
    color: #333;
  }
}

好了,我相信聰明的你已經(jīng)很好的掌握了這兩個方法,那我們?nèi)タ匆幌耬lement是怎么去實(shí)現(xiàn)的吧。
其實(shí)上述的第二個例子已經(jīng)道出一二,我們看一下源碼:

$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;

$--breakpoints: (
  'xs' : (max-width: $--sm - 1),
  'sm' : (min-width: $--sm),
  'md' : (min-width: $--md),
  'lg' : (min-width: $--lg),
  'xl' : (min-width: $--xl)
);
/* Break-points
 -------------------------- */
@mixin res($key, $map: $--breakpoints) {
  // 循環(huán)斷點(diǎn)Map,如果存在則返回
  @if map-has-key($map, $key) {
    @media only screen and #{inspect(map-get($map, $key))} {
      @content;
    }
  } @else {
    @warn "Undefeined points: `#{$map}`";
  }
}
@include res(xs) {
  @for $i from 0 through 24 {
    .el-col-xs-#{$i} {
      width: (1 / 24 * $i * 100) * 1%;
    }

    .el-col-xs-offset-#{$i} {
      margin-left: (1 / 24 * $i * 100) * 1%;
    }
  }
}
@include res(sm) {
  ...
}
@include res(md) {
  ...
}
@include res(lg) {
  ...
}
@include res(xl) {
  ...
}

這樣我們就會在不同的屏幕尺寸下進(jìn)行不同的長度以及間隔的展示了,這樣去寫我們的媒體查詢是不是很棒呢?

到此這篇關(guān)于Element-ui Layout布局(Row和Col組件)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Element Layout布局內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue頁面圖片不顯示問題解決方案

    vue頁面圖片不顯示問題解決方案

    這篇文章主要介紹了vue頁面圖片不顯示問題解決方案,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • vue中的ElementUI的使用詳解

    vue中的ElementUI的使用詳解

    本文通過實(shí)例代碼給大家介紹了vue中的ElementUI的使用,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • vue通過watch對input做字?jǐn)?shù)限定的方法

    vue通過watch對input做字?jǐn)?shù)限定的方法

    本篇文章主要介紹了vue通過watch對input做字?jǐn)?shù)限定的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • vue-vuex中使用commit提交mutation來修改state的方法詳解

    vue-vuex中使用commit提交mutation來修改state的方法詳解

    今天小編就為大家分享一篇vue-vuex中使用commit提交mutation來修改state的方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue-pdf插件實(shí)現(xiàn)pdf文檔預(yù)覽方式(自動分頁預(yù)覽)

    vue-pdf插件實(shí)現(xiàn)pdf文檔預(yù)覽方式(自動分頁預(yù)覽)

    這篇文章主要介紹了vue-pdf插件實(shí)現(xiàn)pdf文檔預(yù)覽方式(自動分頁預(yù)覽),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • vue3項(xiàng)目中封裝axios的示例代碼

    vue3項(xiàng)目中封裝axios的示例代碼

    這篇文章主要介紹了vue3項(xiàng)目中封裝axios的示例代碼,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • vue+Element實(shí)現(xiàn)分頁效果

    vue+Element實(shí)現(xiàn)分頁效果

    這篇文章主要為大家詳細(xì)介紹了vue+Element實(shí)現(xiàn)分頁效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Vue3父子組件間傳參通信的四種方式

    Vue3父子組件間傳參通信的四種方式

    近期學(xué)習(xí)vue3的父子組件之間的傳值,發(fā)現(xiàn)跟vue2的并沒有太大的區(qū)別,下面這篇文章主要給大家介紹了關(guān)于Vue3父子組件間傳參通信的四種方式,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • vue解決一個方法同時發(fā)送多個請求的問題

    vue解決一個方法同時發(fā)送多個請求的問題

    今天小編就為大家分享一篇vue解決一個方法同時發(fā)送多個請求的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 解析Vue2 dist 目錄下各個文件的區(qū)別

    解析Vue2 dist 目錄下各個文件的區(qū)別

    本篇文章主要介紹了解析Vue2 dist 目錄下各個文件的區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11

最新評論