Element分析(組件篇)——Alert

index.js

常規做法,添加install方法來方便作為插件使用。

import Alert from './src/main';

Alert.install = function(Vue) {
  Vue.component(Alert.name, Alert);
};

export default Alert;

整體

首先分析一下其模板結構。

<template>
  <transition name="el-alert-fade">
    <div class="el-alert" :class="[ typeClass ]" v-show="visible">
      <i class="el-alert__icon" :class="[ iconClass, isBigIcon ]" v-if="showIcon"></i>
      <div class="el-alert__content">
        <span class="el-alert__title" :class="[ isBoldTitle ]" v-if="title">{{ title }}</span>
        <slot>
          <p class="el-alert__description" v-if="description">{{ description }}</p>
        </slot>
        <i class="el-alert__closebtn" :class="{ 'is-customed': closeText !== '', 'el-icon-close': closeText === '' }" v-show="closable" @click="close()">{{closeText}}</i>
      </div>
    </div>
  </transition>
</template>

最外層transition

首先,最外層是一個名為el-alert-fade的過渡動畫,查詢發現,它只是簡單的改變了透明度。

<transition name="el-alert-fade">
</transition>
  .el-alert-fade-enter,
  .el-alert-fade-leave-active {
    opacity: 0;
  }````

## el-alert包裹
然后,里面是一層`el-alert 類`的`div`用來包裹整個組件,其中一個屬性是根據傳遞`props`的`type`類型改變樣式,另一個是根據`visible`決定是否顯示。

```html
<div class="el-alert" :class="[ typeClass ]" v-show="visible">
</div>

type是一個計算屬性,代碼如下:

props: {
  type: {
    type: String,
    default: 'info'
  }
}

computed: {
  typeClass() {
    return `el-alert--${ this.type }`;  // 根據傳遞的type返回不同的類
  }
}

再往里面,是一個i標簽和一個div標簽,前者是相應的圖標,后者是警告具體的內容。

圖標

圖標通過兩個類控制樣式,它們都是計算屬性,其中iconClass決定圖標類型,isBigIcon決定圖標大小,而showIcon是傳遞來的props決定是否顯示這個圖標。其代碼如下:

<i class="el-alert__icon" :class="[ iconClass, isBigIcon ]" v-if="showIcon"></i>
props: {
  showIcon: {
    type: Boolean,
    default: false
  }
}

computed: {
  iconClass() {
    return TYPE_CLASSES_MAP[this.type] || 'el-icon-information';
  },

  isBigIcon() {
    return this.description ? 'is-big' : '';
  }
}

其中TYPE_CLASSES_MAP是一個常量對象,用來做map,根據傳遞的type來決定相應的類名。

const TYPE_CLASSES_MAP = {
  'success': 'el-icon-circle-check',
  'warning': 'el-icon-warning',
  'error': 'el-icon-circle-cross'
};

isBigIcon是根據props中的description來決定的,當存在描述內容的時候就使用大的圖標。

props: {
  description: {
    type: String,
    default: ''
  },
}

主體內容

接下來是主要的內容部分,包括標題、內容和關閉按鈕三個部分。

標題

標題是由名為titleprop來決定的,包含一個isBoldTitle的計算屬性來決定是否粗體,以及根據title是否存在來決定是否顯示這一部分。

<span class="el-alert__title" :class="[ isBoldTitle ]" v-if="title">{{ title }}</span>
computed: {
  isBoldTitle() {
    return this.description ? 'is-bold' : '';
  }
}

警告描述

然后是最為主要的描述部分,這部分是一個slot,這使得,這一部分可以自定義,也可以通過傳遞description這一prop來決定內容。

<slot>
  <p class="el-alert__description" v-if="description">{{ description }}</p>
</slot>

關閉按鈕

最后是關閉按鈕的實現。

<i
  class="el-alert__closebtn"
  :class="{ 'is-customed': closeText !== '', 'el-icon-close': closeText === '' }"
  v-show="closable"
  @click="close()">
  {{closeText}}
</i>

不難看出,做了如下處理:

  1. 存在closeText這一prop的內容的話,會自定義關閉內容;
  2. 會根據closable這一prop決定是否顯示該關閉按鈕;
  3. 綁定單擊時觸發事件close()

其中closeTextclosable的代碼如下:

props: {
  closable: {
    type: Boolean,
    default: true
  },
  closeText: {
    type: String,
    default: ''
  },
}

close會將visible設置為false從而關閉該警告,并且觸發close事件。

methods: {
  close() {
    this.visible = false;
    this.$emit('close');
  }
},
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容