网站首页 > 技术文章 正文
前言
一个页面有多个按钮,每个按钮都要添加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 组件库
- 1507℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 502℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 484℃MySQL service启动脚本浅析(r12笔记第59天)
- 464℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 462℃启用MySQL查询缓存(mysql8.0查询缓存)
- 442℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 422℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 418℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)