当前位置:首页 » 《关于电脑》 » 正文

在Vue3中高级前端是这样给按钮添加loading效果的

2 人参与  2024年09月16日 13:21  分类 : 《关于电脑》  评论

点击全文阅读


前言

一个页面有多个按钮,每个按钮都要添加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

 


点击全文阅读


本文链接:http://zhangshiyu.com/post/160677.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1