3.16 Alert 警告
0x00 简介
组件 Alert 用于警告提示,展现需要关注的信息。本文将深入分析源码,剖析其实现原理,耐心读完,相信会对您有所帮助。组件源码实现详见packages/alert/src/main.vue 。 🔗 组件文档 Alert 🔗 gitee源码 main.vue
更多组件剖析详见 👉 📚 Element 2 源码剖析组件总览 。
0x01 组件源码
template 模板内容
组件模板创建一个class名为el-alert的<div> 元素根节点 1️⃣,包含两个子节点 :左侧的Icon图标``2️⃣、右侧的文字内容区域 3️⃣。 组件使用内置 transition 实现el-alert-fade 淡入淡出效果。
组件DOM结构渲染如下 👇:
<template>
<transition name="el-alert-fade">
<div
class="el-alert"
:class="[typeClass, center ? 'is-center' : '', 'is-' + effect]"
v-show="visible"
role="alert"
>
<!-- icon 图标 -->
<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 || $slots.title">
<slot name="title">{{ title }}</slot>
</span>
<!-- 辅助性文字介绍 -->
<p class="el-alert__description" v-if="$slots.default && !description"><slot></slot></p>
<p class="el-alert__description" v-if="description && !$slots.default">{{ description }}</p>
<!-- 关闭按钮 -->
<i class="el-alert__closebtn" :class="{ 'is-customed': closeText !== '',
'el-icon-close': closeText === '' }" v-show="closable" @click="close()">
{{closeText}}
</i>
</div>
</div>
</transition>
</template>1️⃣ 根节点
根据传入prop的属性值动态添加class。
计算属性
typeClass根据type属性值生成不同类型样式 class ,el-alert--[success/warning/info/error]。根据
center属性值生成is-center,让图标文字水平居中。根据
effect属性值生成主题样式is-[light/dark]。
v-show="visible"使用 Data Property 的visible属性控制组件显示隐藏。组件虽为页面中的非浮层元素不会自动消失,但支持手动关闭隐藏。role="alert"表示当前元素的类型,用于ARIA无障碍访问设置。
根节点元素内部使用flex布局。两个子节点交叉轴的中点对齐。
is-center 通过设定属性justify-content 定义了主轴上的对齐方式,实现两个子节点水平居中。
2️⃣ Icon图标
该节点是一个Icon 图标元素,表示某种状态时提升可读性,图标节点是否渲染可见根据 showIcon属性值决定 v-if="showIcon" 。
静态样式
el-alert__icon定义图标默认尺寸。使用计算属性
iconClassisBigIcon动态添加样式。计算属性
iconClass根据type属性值生成不同类型 icon class ,el-icon-[success/warning/info/error]。计算属性
isBigIcon根据 辅助性文字内容是否设置,生成图标大尺寸样式is-big。
Icon 不同大小尺寸效果 👇:
3️⃣ 文字内容区域
该节点是一个class 名为el-alert__content的<div> 元素,内容包含三个节点: 标题 4️⃣ 、 辅助性文字 5️⃣、 关闭按钮 6️⃣ 。
文字内容区域 DOM 结构渲染如下 👇:
标题、辅助性文字节点提供了具名插槽和匿名插槽,分发内容时需要指明slot#name,否则内容都会分发给匿名插槽。
4️⃣ 标题
该节点是一个class 名为el-alert__title的<span> 元素,包裹着具名插槽 title。
只有在 title属性值是 truthy 或者向该插槽分发内容时,该节点才会被渲染。title 是插槽的后备内容。若两者都设置了(传入title值而且向该插槽提供内容),渲染展示内容为插槽分发内容。
使用计算属性 isBoldTitle 动态添加样式。 isBoldTitle 根据辅助性文字内容是否设置,生成样式is-big 加粗title字体,用于区分与辅助性文字的主次。
5️⃣ 辅助性文字
该节点是一个class 名为el-alert__description的<p>段落元素。该节点提供了匿名插槽或 description属性值,但是两者只能同时设置一项,才能正常显示。
当然可以改成如下逻辑,默认显示description属性值,插槽分发内容后优先显示后者。
基于很多组件的逻辑实现: prop属性大多作为插槽的后备内容, 暂时还不知为啥提供这么对立条件,有他无我!
6️⃣ 关闭按钮
节点默认是一个名为el-icon-close的Icon 图标,提供close事件来设置关闭时的回调。通过 closable属性决定是否可关闭。
若设置closeText属性值自定义关闭按钮,此时节点为包裹文本的 <i>元素。
关闭按钮位置偏移至右上角,样式el-alert__closebtn定义如下:
attributes 属性
组件定义了8个prop 。
title
标题
string
—
—
type
类型
string
success/warning/info/error
info
description
辅助性文字
string
—
—
closable
是否可关闭
boolean
—
true
center
文字是否居中
boolean
—
true
close-text
关闭按钮自定义文本
string
—
—
show-icon
是否显示图标
boolean
—
false
effect
选择提供的主题
string
light/dark
light
effect 提供了自定义验证函数,提供了默认值light。 若传入effect值不是以下light/dark其中之一,会生成无效的样式is-[effect],导致组件样式无法正常加载。
计算属性
typeClass
根据 type 属性值生成不同类型主题样式(背景颜色、文字颜色) el-alert-[success/warning/info/error]。
iconClass
计算属性iconClass 根据 type 属性值生成不同类型 icon class el-icon-[success/warning/info/error]。
若传入type值不是以下success/warning/error其中之一,都会生成el-icon-info,所以type默认值等于info。
isBigIcon
根据辅助性文字内容是否设置,只有在 title属性值是 truthy 或者向该插槽分发内容时,生成样式is-big 加粗title字体,用于区分与辅助性文字的主次。
Icon 根据组件内容多少(高度也会调整),动态调整尺寸展示更加协调 👇:
isBoldTitle
根据辅助性文字内容是否设置,只有在 title属性值是 truthy 或者向该插槽分发内容时,生成图标大尺寸样式is-big
close 事件
组件监听按钮的 click 事件 。当点击关闭按钮时,触发 click 事件,执行 close()方法,设置visible属性值 false,隐藏组件;调用 this.$emit('close') 触发当前实例上的close事件 。
0x02 组件样式
src/alert.scss
组件样式源码 packages\theme-chalk\src\alert.scss 使用混合指令 b、e 、m、when 嵌套生成组件样式。
lib/alert.css
前文可知使用 gulpfile.js编译 scss 文件转换为CSS,经过浏览器兼容、格式压缩,最后生成 packages\theme-chalk\lib\alert.scss,内容格式如下。
0x03 📚参考
最后更新于