elementUI源碼分析-03-container、button巍杈、link

一忧饭、container布局容器

用于布局的容器組件,方便快速搭建頁(yè)面的基本結(jié)構(gòu)筷畦。

image.png

<el-container>:外層容器词裤。當(dāng)子元素中包含 <el-header> 或 <el-footer>時(shí)刺洒,全部子元素會(huì)垂直上下排列,否則會(huì)水平左右排列吼砂。

<el-header>:頂欄容器逆航。

<el-aside>: 側(cè)邊欄容器。

<el-main>:主要區(qū)域容器渔肩。

<el-footer>:底欄容器因俐。

<el-container> 的子元素只能是后四者,后四者的父元素也只能是 <el-container>周偎。

也就是說(shuō)抹剩,<el-container><el-header>蓉坎,<el-aside>澳眷,<el-main><el-footer>只能是組合出道蛉艾, 因?yàn)橐陨喜捎昧薴lex 布局钳踊,也就是說(shuō)這套組件就是使用了flex布局,是flex布局屬性排列組合后的各種布局方式勿侯。

el-container

el-container這個(gè)組件只接受一個(gè)參數(shù)就是direction拓瞪,用來(lái)描述子元素的排列方向.
默認(rèn)情況下,如果子元素中有el-header或el-footer時(shí)為豎向排列罐监,其余情況下默認(rèn)橫向排列吴藻。

源碼如下

<template>
  <section class="el-container" :class="{ 'is-vertical': isVertical }">
    <slot></slot>
  </section>
</template>

<script>
  export default {
    name: 'ElContainer',
    componentName: 'ElContainer',
    props: {
      direction: String
    },
    computed: {
      isVertical() {
        if (this.direction === 'vertical') {
          return true;
        } else if (this.direction === 'horizontal') {
          return false;
        }
        // 子元素中有 el-header 或 el-footer 時(shí)為 vertical,否則為 horizontal
        return this.$slots && this.$slots.default
          ? this.$slots.default.some(vnode => {
            const tag = vnode.componentOptions && vnode.componentOptions.tag;
            return tag === 'el-header' || tag === 'el-footer';
          })
          : false;
      }
    }
  };
</script>

默認(rèn)的el-container容器有一個(gè)el-container類名弓柱,用來(lái)設(shè)置默認(rèn)style樣式

.el-container {
    display: flex;
    flex-direction: row;
    flex: 1;
    flex-basis: auto;
    box-sizing: border-box;
    min-width: 0;
}

通過(guò)接收的direction的值沟堡,在結(jié)合computed的isVertical屬性,判斷是否給元素添加is-vertical的class類名矢空。如果有航罗,則用is-vertical的樣式去覆蓋el-container的子元素排放方式的樣式。

.el-container {
    display: flex;
    flex-direction: row;
    flex: 1;
    flex-basis: auto;
    box-sizing: border-box;
    min-width: 0;
}
.el-container.is-vertical {
    flex-direction: column;
}

el-header

el-header組件屁药,只接受一個(gè)height屬性粥血,用來(lái)添加style設(shè)置高度,默認(rèn)為60px酿箭。

源碼如下

<template>
  <header class="el-header" :style="{ height }">
    <slot></slot>
  </header>
</template>

<script>
  export default {
    name: 'ElHeader',

    componentName: 'ElHeader',

    props: {
      height: {
        type: String,
        default: '60px'
      }
    }
  };
</script>

el-header的默認(rèn)樣式

.el-header{
    text-align: center;
    background-color: #b3c0d1;
    color: #333;
    line-height: 60px;
    box-sizing: border-box;
    flex-shrink: 0;
    padding: 0 20px;
}

el-aside

el-aside只接收一個(gè)width組件复亏,用來(lái)設(shè)置側(cè)邊欄的寬度,默認(rèn)是300px

<template>
  <aside class="el-aside" :style="{ width }">
    <slot></slot>
  </aside>
</template>

<script>
  export default {
    name: 'ElAside',

    componentName: 'ElAside',

    props: {
      width: {
        type: String,
        default: '300px'
      }
    }
  };
</script>

el-aside默認(rèn)樣式

.el-aside{
    background-color: #d3dce6;
    text-align: center;
    line-height: 300px;
    color: #333;
    overflow: auto;
    box-sizing: border-box;
    flex-shrink: 0;
}

el-main

el-main只是一個(gè)包括的容器

<template>
  <main class="el-main">
    <slot></slot>
  </main>
</template>

<script>
  export default {
    name: 'ElMain',
    componentName: 'ElMain'
  };
</script>

el-main的默認(rèn)樣式

.el-main{
    background-color: #e9eef3;
    color: #333;
    text-align: center;
    line-height: 160px;
    display: block;
    flex: 1;
    flex-basis: auto;
    padding: 20px;
    overflow: auto;
}

el-footer

el-footer與el-hearder類似缭嫡,只接收一個(gè)height屬性缔御,用來(lái)設(shè)置footer的高度。

<template>
  <footer class="el-footer" :style="{ height }">
    <slot></slot>
  </footer>
</template>

<script>
  export default {
    name: 'ElFooter',

    componentName: 'ElFooter',

    props: {
      height: {
        type: String,
        default: '60px'
      }
    }
  };
</script>

el-footer的默認(rèn)樣式

.el-footer{
    text-align: center;
    background-color: #b3c0d1;
    color: #333;
    line-height: 60px;
    padding: 0 20px;
    flex-shrink: 0;
    box-sizing: border-box;
}

二妇蛀、button

el-button實(shí)際上就是對(duì)原生button的再封裝耕突。


button

el-button組件的引用方式如下

<el-button>默認(rèn)按鈕</el-button>

el-button的參數(shù)列表如下

參數(shù) 說(shuō)明 類型 可選值 默認(rèn)值
size 尺寸 string medium / small / mini -
type 類型 string primary / success / warning / danger / info / text -
plain 是否樸素按鈕 boolean false
round 是否圓角按鈕 boolean false
circle 是否圓形按鈕 boolean false
loading 是否加載中狀態(tài) boolean false
disabled 是否禁用狀態(tài) boolean false
icon 圖標(biāo)類名 string
autofocus 是否默認(rèn)聚焦 boolean false
native-type 原生type屬性 string button / submit / reset button

再結(jié)合el-button源碼笤成,看一下具體原理

<template>
  <button
    class="el-button"
    @click="handleClick"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :class="[
      type ? 'el-button--' + type : '',
      buttonSize ? 'el-button--' + buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }
    ]"
  >
    <i class="el-icon-loading" v-if="loading"></I>
    <i :class="icon" v-if="icon && !loading"></I>
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>
<script>
  export default {
    name: 'ElButton',

    inject: {
      elForm: {
        default: ''
      },
      elFormItem: {
        default: ''
      }
    },

    props: {
      type: {
        type: String,
        default: 'default'
      },
      size: String,
      icon: {
        type: String,
        default: ''
      },
      nativeType: {
        type: String,
        default: 'button'
      },
      loading: Boolean,
      disabled: Boolean,
      plain: Boolean,
      autofocus: Boolean,
      round: Boolean,
      circle: Boolean
    },

    computed: {
      _elFormItemSize() {
        return (this.elFormItem || {}).elFormItemSize;
      },
      buttonSize() {
        return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
      },
      buttonDisabled() {
        return this.disabled || (this.elForm || {}).disabled;
      }
    },

    methods: {
      handleClick(evt) {
        this.$emit('click', evt);
      }
    }
  };
</script>

el-button的默認(rèn)樣式如下

.el-button {
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: #fff;
  border: 1px solid #dcdfe6;
  color: #606266;
  -webkit-appearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: .1s;
  font-weight: 500;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  padding: 12px 20px;
  font-size: 14px;
  border-radius: 4px;
}

display: inline-block; 表示其為內(nèi)聯(lián)元素,可橫向排列
white-space: nowrap; 表示文本不換行
cursor: pointer; 鼠標(biāo)滑過(guò)顯示小手形狀
-webkit-appearance: none; 將按鈕原始樣式去掉
line-height: 1; 行高等于字體大小

type: 通過(guò)接受type值眷茁,來(lái)生成描述背景色等的lass名炕泳、比如type=primary, 即el-button--primary,用來(lái)設(shè)置按鈕的背景色,字體顏色上祈、邊框顏色培遵。

.el-button--primary {
    color: #fff;
    background-color: #409eff;
    border-color: #409eff;
}

size: 通過(guò)設(shè)置size,來(lái)生成描述按鈕大小的class名雇逞,比如size=small, 即el-button--small荤懂。

.el-button--small {
    padding: 9px 15px;
    font-size: 12px;
    border-radius: 3px;
}

plain: 通過(guò)設(shè)置plain,用來(lái)生成描述對(duì)應(yīng)type下的樸素樣式的按鈕塘砸、

.button--primary.is-plain {
    color: #409eff;
    background: #ecf5ff;
    border-color: #b3d8ff;
}

round : 用來(lái)描述是否是圓角按鈕节仿,來(lái)生成對(duì)應(yīng)描述圓角的class名,is-round

.el-button.is-round {
    border-radius: 20px;
    padding: 12px 23px;
}

circle: 是否是原型按鈕掉蔬,來(lái)生成對(duì)應(yīng)50%圓角的class名廊宪,is-circle

.el-button.is-circle {
    border-radius: 50%;
    padding: 12px;
}

loading : 是否是加載中按鈕,如果是加載中的按鈕女轿,則給元素添加el-icon-loading類箭启,添加在加載的圖標(biāo)
disabled : 是否是禁用狀態(tài),添加對(duì)應(yīng)的類名is-disabled蛉迹,并且給原生button設(shè)置disabled="disabled"傅寡,使其不可點(diǎn)擊

.el-button.is-disabled{
  cursor: not-allowed;
}
<button disabled="disabled" type="button" class="el-button el-button--primary is-disabled"><!----><!----><span>主要按鈕</span></button>

icon: 通過(guò)設(shè)置icon,可以添加的內(nèi)部提供的圖標(biāo)
autofocus : 用來(lái)設(shè)置按鈕是否聚焦北救,如果autofocus=true,則給原生button設(shè)置autofocus="autofocus"
native-type : 用來(lái)設(shè)置原生button的type屬性荐操,用來(lái)描述按鈕的類型,即button珍策、reset托启、submit

inject是跟表單相關(guān)的,等后面表單再說(shuō)吧攘宙。

三屯耸、buttonGroup

按鈕組

buttonGroup
<el-button-group>
  <el-button type="primary" icon="el-icon-arrow-left">上一頁(yè)</el-button>
  <el-button type="primary">下一頁(yè)<i class="el-icon-arrow-right el-icon--right"></i></el-button>
</el-button-group>

源碼如下

<template>
  <div class="el-button-group">
    <slot></slot>
  </div>
</template>
<script>
  export default {
    name: 'ElButtonGroup'
  };
</script>

el-button-group就是用來(lái)嵌套一組el-button,并且相鄰兩個(gè)按鈕內(nèi)側(cè)的圓角去掉,且有一條空白線相連蹭劈。具體實(shí)現(xiàn)的style如下

// 圓角設(shè)置
.el-button-group{
  display: inline-block;
  vertical-align: middle;
}
.el-button-group>.el-button:not(:last-child) {
    margin-right: -1px;
}
.el-button-group>.el-button:first-child {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.el-button-group>.el-button:last-child {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}
.el-button-group>.el-button:not(:first-child):not(:last-child) {
    border-radius: 0;
}
// 空白線
.el-button-group .el-button--primary:first-child {
    border-right-color: hsla(0,0%,100%,.5);
}
.el-button-group .el-button--primary:not(:first-child):not(:last-child) {
    border-left-color: hsla(0,0%,100%,.5);
    border-right-color: hsla(0,0%,100%,.5);
}
button-group .el-button--primary:last-child {
    border-left-color: hsla(0,0%,100%,.5);
}

其實(shí)就是運(yùn)用選擇器疗绣,將第一個(gè)按鈕右側(cè)圓角,最后一個(gè)按鈕左側(cè)圓角铺韧,以及中間按鈕的全部圓角去掉持痰,即形成了圓角設(shè)置,空白線也是類似處理祟蚀。因?yàn)榘粹o默認(rèn)都有border工窍,顏色和按鈕主體顏色一致,這里只是修改了border的顏色

四前酿、link

文字超鏈接

link
<div>
  <el-link  target="_blank">默認(rèn)鏈接</el-link>
</div>

參數(shù)如下

參數(shù) 說(shuō)明 類型 可選值 默認(rèn)值
type 類型 string primary / success / warning / danger / info default
underline 是否下劃線 boolean true
disabled 是否禁用狀態(tài) boolean false
href 原生 href 屬性 string
icon 圖標(biāo)類名 string -

el-link患雏,其實(shí)是對(duì)原生a標(biāo)簽的封裝。

源碼如下

<template>
  <a
    :class="[
      'el-link',
      type ? `el-link--${type}` : '',
      disabled && 'is-disabled',
      underline && !disabled && 'is-underline'
    ]"
    :href="disabled ? null : href"
    v-bind="$attrs"
    @click="handleClick"
  >

    <i :class="icon" v-if="icon"></I>

    <span v-if="$slots.default" class="el-link--inner">
      <slot></slot>
    </span>

    <template v-if="$slots.icon"><slot v-if="$slots.icon" name="icon"></slot></template>
  </a>
</template>

<script>

export default {
  name: 'ElLink',

  props: {
    type: {
      type: String,
      default: 'default'
    },
    underline: {
      type: Boolean,
      default: true
    },
    disabled: Boolean,
    href: String,
    icon: String
  },

  methods: {
    handleClick(event) {
      if (!this.disabled) {
        if (!this.href) {
          this.$emit('click', event);
        }
      }
    }
  }
};
</script>

el-link的默認(rèn)樣式如下

.el-link {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    position: relative;
    text-decoration: none;
    outline: none;
    cursor: pointer;
    padding: 0;
    font-size: 14px;
    font-weight: 500;
}

type : 通過(guò)設(shè)置type罢维,添加對(duì)應(yīng)的class類淹仑,給a標(biāo)簽設(shè)置對(duì)應(yīng)的字體顏色

.el-link.el-link--primary {
    color: #409eff;
}

underline : 是否有下滑線,如果添加肺孵,那么在hover的時(shí)候匀借,會(huì)添加一個(gè)after偽類來(lái)創(chuàng)建下劃線

.el-link.is-underline:hover:after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 0;
    bottom: 0;
    border-bottom: 1px solid #409eff;
}
.el-link.el-link--default:after {
    border-color: #409eff;
}

disabled: 是否是禁用狀態(tài),如果設(shè)置了平窘,會(huì)根據(jù)對(duì)應(yīng)type吓肋,設(shè)置對(duì)應(yīng)樣式

.el-link.el-link--danger {
    color: #f56c6c;
}
.el-link.el-link--danger.is-disabled {
    color: #fab6b6;
}

href : 即設(shè)置原生a標(biāo)簽的href屬性
icon: 通過(guò)設(shè)置icon,可以添加的內(nèi)部提供的圖標(biāo)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瑰艘,一起剝皮案震驚了整個(gè)濱河市是鬼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌紫新,老刑警劉巖均蜜,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異芒率,居然都是意外死亡囤耳,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門偶芍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)充择,“玉大人,你說(shuō)我怎么就攤上這事腋寨〈掀蹋” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵萄窜,是天一觀的道長(zhǎng)铃剔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)查刻,這世上最難降的妖魔是什么键兜? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮穗泵,結(jié)果婚禮上普气,老公的妹妹穿的比我還像新娘。我一直安慰自己佃延,他們只是感情好现诀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布夷磕。 她就那樣靜靜地躺著,像睡著了一般仔沿。 火紅的嫁衣襯著肌膚如雪坐桩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天封锉,我揣著相機(jī)與錄音绵跷,去河邊找鬼。 笑死成福,一個(gè)胖子當(dāng)著我的面吹牛碾局,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奴艾,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼净当,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了握侧?” 一聲冷哼從身側(cè)響起蚯瞧,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎品擎,沒想到半個(gè)月后埋合,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萄传,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年甚颂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秀菱。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡振诬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衍菱,到底是詐尸還是另有隱情赶么,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布脊串,位于F島的核電站辫呻,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏琼锋。R本人自食惡果不足惜放闺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缕坎。 院中可真熱鬧怖侦,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至旗吁,卻和暖如春踩萎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背很钓。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留董栽,地道東北人码倦。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像锭碳,于是被迫代替她去往敵國(guó)和親袁稽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Container容器:用于布局的容器組件擒抛,方便快速的搭建頁(yè)面的基本結(jié)構(gòu) <el-container>:外層容器推汽,...
    聽書先生閱讀 5,051評(píng)論 0 2
  • 一個(gè)src文件夾和一個(gè)index.js,src文件夾放組件歧沪,index.js注冊(cè)組件并導(dǎo)出 分析從三個(gè)方面著手:D...
    海淀萌狗閱讀 415評(píng)論 0 0
  • VUE VUE是一個(gè)用MVVM模式來(lái)做項(xiàng)目的一個(gè)框架 首先 說(shuō)一下Vue里面的常用指令 1歹撒、 v-model:將...
    李先生Mr_Li閱讀 815評(píng)論 0 0
  • 【部件中心】->【配件】頁(yè)面 需求描述 1.機(jī)型篩選 根據(jù)機(jī)型(機(jī)器主型號(hào)+機(jī)器子型號(hào))對(duì)頁(yè)面數(shù)據(jù)進(jìn)行篩選。 下拉...
    Sunshine_488c閱讀 395評(píng)論 0 0
  • jquery介紹 jQuery是目前使用最廣泛的javascript函數(shù)庫(kù) 據(jù)統(tǒng)計(jì)诊胞,全世界排名前100萬(wàn)的網(wǎng)站暖夭,有...
    就是這么帥_567e閱讀 1,140評(píng)論 0 0