1.代码
<template>
<div class="loading-box">
<div class="circle-container">
<svg width="75" height="75" class="move-left-to-right">
<circle cx="37.5" cy="37.5" r="26" stroke="white" stroke-width="2" fill="transparent" stroke-dasharray="130" />
</svg>
<svg width="50" height="50" class="move-right-to-left">
<circle cx="25" cy="25" r="16" stroke="white" stroke-width="2" fill="transparent" stroke-dasharray="80" />
</svg>
</div>
<div v-if="text" class="text">{{ text }}</div>
</div>
</template>
<script setup lang="ts">
defineProps({
text: {
type: String,
default: '',
},
});
</script>
<style lang="scss" scoped>
.loading-box {
position: absolute;
inset: 0;
z-index: 999;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgb(0 0 0 / 45%);
}
.circle-container {
position: relative;
width: 80px;
height: 80px;
}
.move-left-to-right {
animation: rotate-clockwise 2s linear infinite;
position: absolute;
top: 0;
left: 0;
}
.move-right-to-left {
animation: rotate-counter-clockwise 2s linear infinite;
position: absolute;
top: 12px;
left: 12px;
}
@keyframes rotate-clockwise {
to {
transform: rotate(360deg);
}
}
@keyframes rotate-counter-clockwise {
to {
transform: rotate(-360deg);
}
}
.text {
margin-top: 10px;
font-family: 'PingFang SC', 'PingFang SC';
font-size: 16px;
font-weight: bold;
line-height: 18px;
color: #fff;
}
</style>
2.解释
这段代码是一个 Vue 组件,它展示了一个加载动画。让我一步步解释一下:
- 在模板中,有一个包含加载动画和可能显示文本的 `loading-box` 的 `div`。加载动画由两个 `svg` 组成,分别是 `move-left-to-right` 和 `move-right-to-left` 类的圆圈。
- `defineProps` 函数是 Vue 3 Composition API 中用于定义 props 的函数。在这个组件中,它定义了一个名为 `text` 的 prop,类型为字符串,默认为空字符串。
- 在样式部分,`.loading-box` 控制整个加载框的样式,设置其为全屏、居中、半透明黑色背景。`.circle-container` 确保两个圆圈的容器大小合适。
- `.move-left-to-right` 和 `.move-right-to-left` 控制两个圆圈的样式和动画。它们通过 `rotate-clockwise` 和 `rotate-counter-clockwise` 关键帧动画,以相反的方向旋转,使得两个圆圈呈现出交替的旋转效果。
- 最后,`.text` 控制可能显示的文本的样式,设置了字体、大小、粗细和颜色。
这个组件通过 Vue 的 props 功能来接受一个 `text` 参数,用以动态显示文本内容。加载动画部分则通过 CSS 的关键帧动画来实现旋转效果,展现出简单而美观的加载状态。
3.svg属性
SVG(可缩放矢量图形)是一种用于描述二维图形和图形应用程序的 XML 标记语言。在你提供的代码中,有两个 `<svg>` 元素,每个元素都包含一个圆圈。
让我解释一下 `<circle>` 元素中的属性:
1. **`cx`**: 这是圆的中心在 x 轴上的坐标值。
2. **`cy`**: 这是圆的中心在 y 轴上的坐标值。
3. **`r`**: 这是圆的半径。
4. **`stroke`**: 这定义了圆的轮廓颜色。
5. **`stroke-width`**: 这定义了圆的轮廓宽度。
6. **`fill`**: 这定义了圆的填充颜色。
7. **`stroke-dasharray`**: 这定义了轮廓的虚线样式,其中值是一个以逗号分隔的数字列表,代表实线和空白部分的长度。
这些属性控制着圆的位置、大小、外观和轮廓样式,允许你创建不同形状和样式的圆圈。
4.使用方式一
import Loading from './Loading.vue';
<Loading v-model:visible="loading" text="Generating..." />
5.命令式使用
// showLoading.ts
import loading from '@/components/AiBackground/loading.vue';
import { createApp } from 'vue';
export default function showLoading(text: string): void {
const app = createApp(loading, {
text
});
const div = document.createElement('div');
document.body.appendChild(div);
app.mount(div);
}
使用
import showLoading from '@/utils/showLoading';
showLoading('loading');
6.使用方式三
createVNode
// showLoading.ts
// import loading from '@/components/AiBackground/loading.vue';
import { createApp } from 'vue';
const loading = {
props: {
text: String,
handler: Function,
},
render(ctx) {
// 使用createVNode
return createVNode('div', {
class: 'loading',
});
},
};
export default function showLoading(text: string, handler: Function): void {
const app = createApp(loading, {
text,
handler,
});
const div = document.createElement('div');
document.body.appendChild(div);
app.mount(div);
}
7.使用jsx
总结合理的封装方便使用