Element 2 組件源碼剖析之Badge標記

這是我參與8月更文挑戰的第6天,活動詳情查看:8月更文挑戰css

0x00 簡介

組件 Badge 通常和其它組件配合使用,用於進數字或狀態標記提醒效果。vue

本文將深刻分析組件 Badge 源碼,剖析其實現原理,耐心讀完,相信會對您有所幫助。 組件文檔 Badgenode

packages/badge/src/main.vue 文件是組件源碼實現。 github源碼 main.vuegit

0x01 template 模板

從模板內容看出,組件封裝一個 <div> 元素,包含兩項內容:github

  1. 提供了 slot ,沒有設置後備內容(默認值);
  2. 使用了內置過渡動畫的<sup>元素,用於定義上標文本。
<template>
  <div class="el-badge"> <slot></slot> <transition name="el-zoom-in-center"> <sup v-show="!hidden && (content || content === 0 || isDot)" v-text="content" class="el-badge__content" :class="[ 'el-badge__content--' + type, { 'is-fixed': $slots.default, 'is-dot': isDot } ]"> </sup> </transition> </div>
</template> 
複製代碼

組件渲染後生成一個 class 值爲 el-badge<div> 元素做爲容器。slot 沒有設置後備內容, 只有在組件包裹內容時纔會進行渲染。生成一個 class 值爲 el-badge__content<sup> 元素定義上標文本,用於實現數字或狀態標記效果,使用內置組件 transition 實現縮放zoom-in-center效果。web

<sup> 的可見性由組件 prop hiddenisDot 和 計算屬性content 進行控制。文本內容爲content屬性值。根據插槽傳值$slots.defaulttypeisDot等屬性值動態添加 class,實現不一樣場景的形式展現。gulp

0x02 attributes 屬性

組件提供了5個 prop瀏覽器

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

  props: {
    value: [String, Number], // 顯示值
    max: Number, // 最大值,超過最大值會顯示 '{max}+'
    isDot: Boolean, // 是否顯示小圓點
    hidden: Boolean, // 是否隱藏 badge
    // 類型
    type: {
      type: String,
      validator(val) {
        return ['primary', 'success', 'warning', 'info', 'danger'].indexOf(val) > -1;
      }
    }
  },

  computed: {
    // 計算屬性 上標顯示內容 根據 isDot、value、max進行判斷計算。
    content() {
      // ...
    }
  }
};
</script>
複製代碼

屬性描述

各屬性功能描述以下:sass

參數 說明 類型 可選值 默認值
value 顯示值 string, number
max 最大值,超過最大值會顯示 '{max}+',要求 value 是 Number 類型 number
is-dot 小圓點 boolean false
hidden 隱藏 badge boolean false
type 類型 string primary / success / warning / danger / info

type 提供了 primary / success / warning / danger / info可選值,提供了自定義驗證函數。markdown

// 自定義驗證函數
type: { 
  validator(val) {
    // 這個值必須匹配下列字符串中的一個
    return ['primary', 'success', 'warning', 'info', 'danger'].indexOf(val) > -1;
  }
}
複製代碼

當 prop 驗證失敗的時候,(開發環境構建版本的) Vue 將會產生一個控制檯的警告。 此時 type 值爲undefined

image.png

計算屬性

計算屬性content值是上標顯示內容。 根據 isDotvaluemax 等prop進行判斷計算。

computed: {
    content() {
      // 小紅點形式
      if (this.isDot) return;

      const value = this.value;
      const max = this.max;
      
      // 數值超過最大值處理
      if (typeof value === 'number' && typeof max === 'number') {
        return max < value ? `${max}+` : value;
      }

      return value;
    }
  }
複製代碼

若使用小圓點形式, isDot 值爲 true if (this.isDot) return;content值爲 undefined

若不使用小圓點形式時,valueNumber 類型且設置了 max,判斷是否超過最大值,超過會顯示 {max}+,其他狀況 content值等於 value值。

<sup>顯隱邏輯

v-show 指令條件 !hidden && (content || content === 0 || isDot) 短路表達式是可知,若 hidden 值爲true隱藏不顯示,後續條件不執行。

若顯示上標hidden 值爲false,則繼續根據顯示內容 content是否存在內容進行判斷, content === 0 邏輯是爲了防止 當 value 爲 0 時,表達式 (content) 返回 false。 使用圓點形式時,由上文可知contentundefinedisDot 值爲true,此時表達式返回 true

動態class

根據 type 會動態的設置 el-badge__content--[type],用於不一樣類型的上標顏色顯示 el-badge__content--[primary/success/warning/danger/info]。當 type 未設置或者不是指定值時,class 值爲el-badge__content--undefined

當組件和其它組件配合使用,包裹內容時提供給插槽值 $slots.default[Vnode],設置 is-fixed固定上標位置-右上角。

若使用小圓點形式時,設置is-dot控制上標的樣式爲紅點。

0x03 組件樣式

src/badge.scss

組件樣式源碼 packages\theme-chalk\src\badge.scss 使用 scss 的混合指令 bemwhen 嵌套生成組件樣式。

// 生成 el-badge
@include b(badge) {
  // ...
  
  // 生成 el-badge__content 
  @include e(content) {
    // ...
    
    // 生成 el-badge__content.is-fixed
    @include when(fixed) {
      // ...
      
      // 生成 el-badge__content.is-fixed.is-dot
      @include when(dot) {
        // ...
      }
    }
    
    // 生成 el-badge__content.is-fixed.is-dot
    @include when(dot) {
      // ...
    }

    @each $type in (primary, success, warning, info, danger) {
      // 生成 .el-badge__content--[primary/success/warning/info/danger]
      @include m($type) {
        // ...
      }
    }
  }
}

複製代碼

lib/badge.scss

前文可知使用 gulpfile.js編譯 scss 文件轉換爲CSS,通過瀏覽器兼容、格式壓縮,最後生成 packages\theme-chalk\lib\badge.scss,內容格式以下。

.el-badge {
  //...
}
.el-badge__content {
  //...
}
.el-badge__content.is-fixed {
  // ...
}
.el-badge__content.is-fixed.is-dot {
  // ...
}
.el-badge__content.is-dot {
  // ...
}
.el-badge__content--primary {
  background-color: #409eff;
}
.el-badge__content--success {
  background-color: #67c23a;
}
.el-badge__content--warning {
  background-color: #e6a23c;
}
.el-badge__content--info {
  background-color: #909399;
}
.el-badge__content--danger {
  background-color: #f56c6c;
}

複製代碼

0x04 📚參考

"sass在線編輯器",sassmeister

0x05 關注專欄

此文章已收錄到專欄中 👇,能夠直接關注。

相關文章
相關標籤/搜索