0x00 简介
组件 Progress
用于展示操作进度,告知用户当前状态和预期。 本文将深入分析源码,剖析其实现原理,耐心读完,相信会对您有所帮助。packages/progress/src/progress.vue
文件是组件源码实现。。 ? 组件文档 Progress ? gitee源码 progress.vue
更多组件剖析详见 ? ? Element 2 源码剖析组件总览 。
0x01 组件源码
template 模板内容
模板创建一个 <div>
元素根节点,class 名为el-result
,包含 4 个子节点 自定义图标
、自定义标题
、自定义二级标题
、自定义底部额外区域
。
每个节点都提供了各自具名slot
, 在向具名插槽提供内容的时候需要指明 slot#name
,否则内容无法正确分发,将被丢弃(未提供匿名插槽)。
<template> <div class="el-result"> <!-- 自定义图标 slot icon --> <div class="el-result__icon"> <slot name="icon"> <component :is="iconElement" :class="iconElement" /> </slot> </div> <!-- 自定义标题 slot title --> <div v-if="title || $slots.title" class="el-result__title"> <slot name="title"> <p>{{ title }}</p> </slot> </div> <!-- 自定义二级标题 slot subTitle --> <div v-if="subTitle || $slots.subTitle" class="el-result__subtitle"> <slot name="subTitle"> <p>{{ subTitle }}</p> </slot> </div> <!-- 自定义底部额外区域 slot extra --> <div v-if="$slots.extra" class="el-result__extra"> <slot name="extra"></slot> </div> </div></template>
自定义图标
该节点是一个class 名为el-result__icon
的<div>
元素包,裹着名为icon
的具名slot
。
插槽提供了后备内容,动态引用svg 图标组件。具体详见下文章节 动态组件 。
自定义标题
该节点是一个class 名为el-result__title
的<div>
元素包,裹着名为title
的具名slot
。
只有在 title
是 truthy
或者向该插槽提供内容时,该节点才会被渲染。若两者都设置了(传入title
值而且向该插槽提供内容),展示内容为插槽分发内容优先级较高。因为 title
是做为插槽的后备内容
。
truthy(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 false
、0
、""
、null
、undefined
和 NaN
以外皆为真值)
自定义二级标题
该节点是一个class 名为el-result__subtitle
的<div>
元素包,裹着名为title
的具名subTitle
。
只有在 subTitle
是 truthy
或者向该插槽提供内容时,该节点才会被渲染。若两者都设置了(传入subTitle
值而且向该插槽提供内容),展示内容为插槽分发内容优先级较高。因为 subTitle
是做为插槽的后备内容
。
自定义底部额外区域
该节点是一个class 名为el-result__extra
的<div>
元素包,裹着名为extra
的具名slot
。只有向该插槽提供内容时v-if="$slots.extra"
,该节点才会被渲染。
动态组件
上文名为icon
的具名slot
的 后备内容
使用了动态组件
,根据传入不同的图标类型icon
,动态引入对应类型svg图标组件。
通过 Vue 的 <component>
元素加一个特殊的 is
attribute 来实现在不同组件之间进行动态切换。
<component :is="iconElement" :class="iconElement" />
svg 组件引入注册。
<script>import IconSuccess from './icon-success.vue';import IconError from './icon-error.vue';import IconWarning from './icon-warning.vue';import IconInfo from './icon-info.vue'; export default { components: { [IconSuccess.name]: IconSuccess, [IconError.name]: IconError, [IconWarning.name]: IconWarning, [IconInfo.name]: IconInfo }, };</script>
计算属性
计算属性 iconElement
根据传入icon
值动态生成 图标名称。用于组件引用和class添加。
const IconMap = { success: 'icon-success', warning: 'icon-warning', error: 'icon-error', info: 'icon-info'};export default { // ... computed: { iconElement() { const icon = this.icon; return icon && IconMap[icon] ? IconMap[icon] : 'icon-info'; } }};
根据 IconMap
定义,若传入的icon
值不是success / warning / info / error
其中一个,返回默认值icon-info
等同于 icon
值为 info
。
iconElement
值范围为 icon-success
, icon-warning
, icon-error
, icon-info
。
svg 样式
iconElement
值 icon-success
、 icon-warning
、 icon-error
、 icon-info
会用于svg图标颜色的自定义。不同类型的class定义了不同的颜色,效果如下:
attributes 属性
组件定义了3 个prop : title
、subTitle
、icon
。
props: { title: { type: String, default: '' }, subTitle: { type: String, default: '' }, icon: { type: String, default: 'info' } },
title
设置标题内容,默认值为 ''
。 具体功能详见上文章节 自定义标题 。
subTitle
设置二级标题内容,默认值为 ''
。 具体功能详见上文章节 自定义二级标题 。
icon
图标类型设置,用于引入指定类型的svg图标、设置图标颜色。 具体功能详见上文章节 计算属性 。
0x03 组件样式
src/result.scss
组件样式源码 packages\theme-chalk\src\result.scss
使用混合指令 b
、e
嵌套生成组件样式。
// 生成 .el-result@include b(result) { // ... // 生成 .el-result__icon svg @include e(icon) { svg { // ... } } // 生成 .el-result__title @include e(title) { // ... // 生成 .el-result__title p p { // ... } } // 生成 .el-result__subtitle @include e(subtitle) { // ... // 生成 .el-result__subtitle p p { // ... } } // 生成 .el-result__extra @include e(extra) { // ... } // 生成 .el-result .icon-success .icon-success { // ... } // 生成 .el-result .icon-error .icon-error { // ... } // 生成 .el-result .icon-info .icon-info { // ... } // 生成 .el-result .icon-warning .icon-warning { // ... }}
lib/result.scss
前文可知使用 gulpfile.js
编译 scss
文件转换为CSS
,经过浏览器兼容、格式压缩,最后生成 packages\theme-chalk\lib\result.scss
,内容格式如下。
.el-result { // ... }.el-result__icon svg { // ... }.el-result__title { // ... }.el-result__title p { // ... }.el-result__subtitle { // ... }.el-result__subtitle p { // ... }.el-result__extra { // ... }.el-result .icon-success { // ... }.el-result .icon-error { // ... }.el-result .icon-info { // ... }.el-result .icon-warning { // ... }
0x04 ?参考
"动态组件",vuejs.org\ "viewBox",MDN\ "Truthy",MDN
0x05 关注专栏
此文章已收录到专栏中 ?,可以直接关注。
原文:https://juejin.cn/post/7101974761596518436