网站首页 > 技术文章 正文
前言
一个页面有多个按钮,每个按钮都要添加loading效果,高级前端是如何在Vue3控制按钮是否显示loading效果的呢?
普通前端
我们先来看看初级普通前端平常是怎么给按钮添加loading效果的:
<script setup >
import { ref } from 'vue'
const asyncFn = () => new Promise(resolve => {
setTimeout(resolve, 3000)
})
const loading1 = ref(false)
const handler1 = async () => {
loading1.value = true
try {
await asyncFn()
} finally {
loading1.value = false
}
}
const loading2 = ref(false)
const handler2 = async () => {
loading2.value = true
try {
await asyncFn()
} finally {
loading2.value = false
}
}
const loading3 = ref(false)
const handler3 = async () => {
loading3.value = true
try {
await asyncFn()
} finally {
loading3.value = false
}
}
</script>
<template>
<el-button type="primary" @click="handler1" :loading="loading1">
按钮1
</el-button>
<el-button @click="handler2" :loading="loading2">
按钮2
</el-button>
<el-button type="primary" plain @click="handler3" :loading="loading3">
按钮3
</el-button>
</template>
通过以上代码可以看到,一个页面有多个按钮,每个按钮都要添加loading效果,所以声明了loading1、loading2、loading3 ...变量来控制按钮是否显示loading效果,非常不优雅。 那么高级前端是如何优雅的给按钮添加loading效果的呢?
高级前端
首先先封装一个MyButton组件:
<script setup >
import { ref, useSlots } from 'vue'
const props = defineProps(['onClick'])
const loading = ref(false)
const clickHandler = async (e) => {
loading.value = true
try {
await props.onClick(e)
} finally {
loading.value = false
}
}
const slots = useSlots()
</script>
<template>
<el-button @click="clickHandler" :loading="loading">
<template v-for="(_, key, i) in slots" :key="i" #[key]>
<slot :name="key" />
</template>
</el-button>
</template>
接下来引用MyButton组件,绑定click事件,返回Promise就可以优雅的给按钮添加一个loading效果了
<script setup >
import MyButton from './MyButton.vue';
const asyncFn = () => new Promise(resolve => {
setTimeout(resolve, 3000)
})
const handler1 = async () => {
// ...
await asyncFn()
}
const handler3 = () => {
// ...
return asyncFn()
}
</script>
<template>
<MyButton type="primary" @click="handler1">
按钮1
</MyButton>
<MyButton @click="asyncFn">
按钮2
</MyButton>
<MyButton type="primary" plain @click="handler3">
<template #loading>
<div class="custom-loading">
<svg class="circular" viewBox="-10, -10, 50, 50">
<path class="path" d="
M 30 15
L 28 17
M 25.61 25.61
A 15 15, 0, 0, 1, 15 30
A 15 15, 0, 1, 1, 27.99 7.5
L 15 15
" style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)" />
</svg>
</div>
</template>
按钮3
</MyButton>
</template>
<style scoped>
.el-button .custom-loading .circular {
margin-right: 6px;
width: 18px;
height: 18px;
animation: loading-rotate 2s linear infinite;
}
.el-button .custom-loading .circular .path {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: var(--el-button-text-color);
stroke-linecap: round;
}
</style>
总结
- 可以通过defineProps(['onEventName'])声明事件,组件内部通过props.onEventName()触发事件,并且可以获取到事件回调函数的返回值,进而组件内部做更多逻辑处理,如给一个按钮组件自动添加loading等
- @eventName本质就是一个语法糖,最后还是会编译为onEventName通过属性的形式 传递给组件。如需了解更多,请查看文章:通过编译源码解析Vue不同方式监听事件的区别
结语
感谢您的耐心阅读,如果觉得这篇文章对您有帮助和启发,麻烦给个大大的赞~
文章转自:https://juejin.cn/post/7378893690145816612
猜你喜欢
- 2024-10-30 基于Web的“戳泡泡”解压小游戏(戳泡泡用英文怎么说)
- 2024-10-30 暗夜发光,独自闪耀,网页暗黑模式下的特效和动效,CSS3实现
- 2024-10-30 HTML多行代码搞定微信8.0的炸裂特效!C/C++怎么能输
- 2024-10-30 Nick_N像素画教程:像素画动画缓入缓出
- 2024-10-30 CSS动画制作(css动画制作电池充电效果)
- 2024-10-30 前端系列:在线认识贝塞尔曲线的运动轨迹(中文版网站)
- 2024-10-30 CSS3 transition过渡效果(css3过度效果)
- 2024-10-30 15个CSS 常见错误,请一定要注意避免
- 2024-10-30 css动画之transition(css transition动画)
- 2024-10-30 daisyUI - 主题漂亮、代码纯净!免费开源的 Tailwind CSS 组件库
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)