3.8 Tag 标签

0x00 简介

组件Tag 多用于标记和分类。 本文将深入分析组件源码,剖析其实现原理,耐心读完,相信会对您有所帮助。packages/tag/src/tag.vue 文件是组件源码实现。 🔗 组件文档 Tag 🔗 github 源码 tag.vue

更多组件剖析详见 👉 📚 Element 2 源码剖析组件总览

0x01 组件源码

使用 渲染函数 创建组件,代码结构如下 👇。

<script>
  export default {
    name: 'ElTag',
    // 组件 prop
    props: {
      // ...
    },
    methods: {
      // 关闭 Tag 时触发的事件
      handleClose(event) {
        // ...
      },
      // 点击 Tag 时触发的事件
      handleClick(event) {
        // ...
      }
    },
    // 计算属性
    computed: {
      // 标签尺寸
      tagSize() {
        // ...
      }
    },
    // 渲染 标签 虚拟DOM
    render(h) {
      // ...
    }
  };
</script>

attributes 属性

组件定义了 8 个 prop

prop详细描述如下(只有 7 个):

参数
说明
类型
可选值
默认值

type

类型

string

success/info/warning/danger

closable

是否可关闭

boolean

false

disable-transitions

是否禁用渐变动画

boolean

false

hit

是否有边框描边

boolean

false

color

背景色

string

size

尺寸

string

medium / small / mini

effect

主题

string

dark / light / plain

light

proptext 虽然定义了,但是在代码中没有被使用。 typesizeeffect 的值若没有匹配指定的字符串,根据值生成无效的 class(样式规则未定义)。

计算属性

tagSize 根据size$ELEMENT动态计算标签的尺寸。

组件定义了 prop size , 则tagSize 值为 size 定义值。若 size 值为 undefined'', tagSize 值为由全局配置 $ELEMENT决定。

$ELEMENT 对象不为空且包含 size 属性, tagSize 值为对象的属性值 $ELEMENT.size;否则 tagSize 值为 undefined,

前文可知,组件入口文件中 install 方法中定义了对象 $ELEMENT 全局配置。其中组件的默认尺寸 size值为''

完整引入组件时,使用 vue.use()注册组件,会执行 install 方法,声明了全局属性 $ELEMENT

按需引入时, 需要手动配置 Vue.prototype.$ELEMENT = { size: 'small', zIndex: 3000 };,若不配置 $ELEMENT 未定义值为 undefined,若此调用 $ELEMENT.size 则会抛出异常Uncaught ReferenceError: $ELEMENT is not defined

表达式 (this.$ELEMENT || {}) 防止$ELEMENT 未定义赋予空对象防止异常调用。

events 事件

点击 Tag 时触发 click 事件。

关闭 Tag 时触发 close 事件。

render() 渲染函数

组件将创建一个 <span> 元素 VNode,动态添加 class,使用内联样式设置背景色,定义了组件点击事件。 <span> 元素包含 2 个子节点

  1. 默认插槽;

  2. 名为el-icon-closeIcon图标,定义了关闭 Tag 时 click 事件。当 closable 值为true时才会渲染。

disableTransitions值为true时,使用内置组件 transition 包裹 <span> 元素实现缩放zoom-in-center效果。

根据组件 prop 动态添加 class

  • 'el-tag' 组件默认样式。

  • type ? 'el-tag--${type}' : '' 设置组件不同类型颜色。若 type 值不是以下success/info/warning/danger其中一个,设置无效(生成无效的 class)。

  • tagSize ? 'el-tag--${tagSize}' : '' 设置组件不同尺寸。若 tagSize 值不是以下medium/small/mini其中一个,设置无效(生成无效的 class)。

  • effect ? 'el-tag--${effect}' : '' 设置组件不同主题。若 effect 值不是以下dark/light/plain其中一个,设置无效(生成无效的 class)。 effect 默认值为 light,对应的 el-tag--light是无效的样式,未定义。

  • hit && 'is-hit' 边框描边效果 。

color 属性定义组件内联样式 backgroundColor,权重较高会覆盖其他样式的颜色。

0x02 组件样式

src/tag.scss

组件样式源码 packages\theme-chalk\src\tag.scss 使用混合指令 bmgenTheme 嵌套生成组件样式。

genTheme() 组件主题

混合指令 genTheme 用于生成组件的主题样式。

Mix 函数是将两种颜色根据一定的比例混合在一起,生成另一种颜色。 前两个参数是想混合的颜色(可以使用颜色变量、十六进制、RGBA、RGB、HSL 或者 HSLA 颜色值),第三个参数是第一种颜色的比例值。

组件主题默认样式直接在 el-tag 下生成 。

结合上述规则生成的主题样式如下

组件样式

组件样式逻辑如下。

lib/tag.scss

前文可知使用 gulpfile.js编译 scss 文件转换为CSS,经过浏览器兼容、格式压缩,最后生成 packages\theme-chalk\lib\tag.scss,内容格式如下。

0x03 📚 参考

“stopPropagation”,MDN “mix funciton color”,sass

最后更新于