0x00 简介
组件 Spinner
用于页面和区块的加载中状态,页面局部处于等待异步数据或正在渲染过程时,合适的加载动效会有效缓解用户的焦虑。 本文将深入分析组件源码,剖析其实现原理,耐心读完,相信会对您有所帮助。packages/spinner/src/spinner.vue
文件是组件源码实现。 🔗 github源码 spinner.vue
更多组件分析详见 👉 📚 Element UI 源码剖析组件总览 。
本专栏的 gitbook
版本地址已经发布 📚《learning element-ui》 ,内容同步更新中!
0x01 Spinner 组件
Spinner.vue
组件是一个隐藏组件,暂未有其他组件使用。
模板创建一个 class 名为el-spinner
的span
元素,包含了一个<circle>
SVG 圆形。
<template>
<span class="el-spinner">
<svg class="el-spinner-inner" viewBox="0 0 50 50" :style="{ width: radius/2 + 'px', height: radius/2 + 'px' }">
<circle class="path" cx="25" cy="25" r="20" fill="none" :stroke="strokeColor" :stroke-width="strokeWidth"></circle>
</svg>
</span>
</template>
<script>
export default {
name: 'ElSpinner',
props: {
type: String,
radius: {
type: Number,
default: 100
},
strokeWidth: {
type: Number,
default: 5
},
strokeColor: {
type: String,
default: '#efefef'
}
}
};
</script>
组件提供了以下 prop
属性。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 无效参数 | string | — |
radius | svg容器大小宽高值 radius/2 ,单位px | number | 100 |
strokeWidth | 图形的轮廓的宽度 | number | 5 |
strokeColor | 图形的外轮廓的颜色 | string | #efefef |
0x02 组件样式
src/spinner.scss
组件样式源码 packages\theme-chalk\src\spinner.scss
使用混合指令 b
嵌套生成组件样式。
// 生成 .el-time-spinner
@include b(time-spinner) {
// ...
}
// 生成 .el-spinner
@include b(spinner) {
// ...
}
// 生成 .el-spinner-inner
@include b(spinner-inner) {
// ...
// 生成 .el-spinner-inner .path
& .path {
// ...
}
}
// 关键帧 CSS动画
@keyframes rotate { /* ... */ }
@keyframes dash { /* ... */ }
lib/spinner.css
前文可知使用 gulpfile.js
编译 scss
文件转换为CSS
,经过浏览器兼容、格式压缩,最后生成 packages\theme-chalk\lib\spinner.css
,内容格式如下。
.el-time-spinner { /* ... */ }
.el-spinner { /* ... */ }
.el-spinner-inner {
animation: rotate 2s linear infinite;
width: 50px;
height: 50px;
}
.el-spinner-inner .path {
stroke: #ececec;
stroke-linecap: round;
animation: dash 1.5s ease-in-out infinite;
}
@keyframes rotate { /* ... */ }
@keyframes dash { /* ... */ }
0x03 CSS 动画
默认的 <circle>
元素展示如下:
使用 @keyframes
at-rule 规则通过在动画序列中定义关键帧(或waypoints)的样式来控制CSS动画序列
定义 <circle>
元素动画关键帧规则 dash
@keyframes dash {
0% {
stroke-dasharray: 1, 150;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -35;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -124;
}
}
.el-spinner-inner .path {
animation: dash 1.5s ease-in-out infinite;
}
添加动画效果后, <circle>
元素展示如下:
定义 <svg>
元素动画关键帧规则 rotate
,用于元素旋转。
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
.el-spinner-inner {
animation: rotate 2s linear infinite;
}
添加动画效果后, <svg>
元素展示如下:
组件中不同元素的关键帧效果叠加,实现了 loding 动效。
组件提供了prop 用于自定义效果,代码如下:
<template>
<el-spinner
:radius="300"
:stroke-width="8"
:stroke-color="'#E6A23C'"
></el-spinner>
</template>
组件效果如下:
由于组件样式 .path
定义了 stroke
属性设置了默认值 #ececec;
,导致stroke-color
设置无效。需要移除该属性才能生效。
@include b(spinner-inner) {
// ...
& .path {
// stroke: #ececec;
stroke-linecap: round;
animation: dash 1.5s ease-in-out infinite;
}
}
📚参考&关联阅读
关注专栏
如果本文对您有所帮助请关注➕、 点赞👍、 收藏⭐!您的认可就是对我的最大支持!
此文章已收录到专栏中 👇,可以直接关注。