首页 > 其他分享 >在Vue3中高级前端是这样给按钮添加loading效果的

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

时间:2024-06-12 12:30:34浏览次数:20  
标签:loading const Vue3 value 按钮 中高级 false asyncFn

前言

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

 

相关源码

总结

  1. 可以通过defineProps(['onEventName'])声明事件,组件内部通过props.onEventName()触发事件,并且可以获取到事件回调函数的返回值,进而组件内部做更多逻辑处理,如给一个按钮组件自动添加loading等
  2. @eventName本质就是一个语法糖,最后还是会编译为onEventName通过属性的形式 传递给组件。如需了解更多,请查看文章:通过编译源码解析Vue不同方式监听事件的区别

结语

感谢您的耐心阅读,如果觉得这篇文章对您有帮助和启发,麻烦给个大大的赞~

文章转自:https://juejin.cn/post/7378893690145816612

 

标签:loading,const,Vue3,value,按钮,中高级,false,asyncFn
From: https://blog.csdn.net/gaotlantis/article/details/139595706

相关文章

  • Vue3——setup语法糖
    setup概述setup是Vue3中新的配置项,值是一个函数,组件中所用到的数据、方法、计算属性、监视等等,均配置在setup中。setup函数返回的对象中的内容,可直接在模版中使用。setup中不能使用this关键字,this是undefined。setup会在beforeCreate()函数之前调用,领先所有的钩子函数执行的......
  • 基于jeecgboot-vue3的Flowable流程--抄送我的功能
    因为这个项目license问题无法开源,更多技术支持与服务请加入我的知识星球。1、抄送我的界面代码如下:<template><divclass="p-2"><!--查询区域--><divclass="jeecg-basic-table-form-container"><a-formref="formRef"@keyup.enter.nati......
  • electron + vue3 自定义窗口:移动,缩放,置顶
    electronmain.jsconst{BrowserWindow,ipcMain}=require('electron');constpath=require("path")constCustomWindow=require('./CustomWindow')constwin=newBrowserWindow({frame:false,transparent:true,......
  • 实现抖音视频滑动功能vue3+swiper
    首先,你需要安装和引入Swiper库。可以使用npm或者yarn进行安装。pnpminstallswiper然后在Vue组件中引入Swiper库和样式。//导入Swiper组件和SwiperSlide组件,用于创建轮播图import{Swiper,SwiperSlide}from'swiper/vue';//导入Swiper的CSS样式,确保轮播图......
  • vue3 高德安徽省边界 密钥必须添加否则会出现无法使用DistrictSearch的方法也不报错
    <template> <divclass="centermap"ref="mapContainer"></div></template><scriptsetuplang="ts">import{ref,onMounted}from'vue';importAMapLoaderfrom'@amap/amap-jsapi-l......
  • 管理数据必备;侦听器watch用法详解,vue2与vue3中watch的变化与差异
    目录一、侦听器(watch)是什么?二、Vue2中的watch(OptionsAPI)2.1、函数式写法2.2、对象式写法    ①对象式基础写法    ②回调函数handler    ③deep属性        ④immediate属性三、Vue3中的watch3.1、向下兼容(Vue2)的Options API3.2......
  • Vue3 运行可以,build 打包发布报错
    Vue多环境配置https://www.cnblogs.com/vipsoft/p/16696640.htmlconfig.jsconstconfig={title:'管理系统(开发)',//开发、测试apiUrl:'http://www.vipsoft.com.cn',version:'v1.0.1'}exportdefaultconfigmain.jsimportconfigfrom......
  • Vue3——创建Vue3工程
    基于Vue-Cli创建现在官方推荐使用create-vue来创建基于Vite的新项目(⚠️VueCLI现已处于维护模式!)#查看@vue/cli版本号,确保@vue/cli版本在4.5.0以上vue--version#没有安装@vue/cil或者版本不在4.5.0以上执行命令#安装或升级@vue/cli(确保安装了node.js)......
  • vue3 通过ref获取元素离顶部的距离
    vue3版本 ^3.2.45[ref].value.$el.getBoundingClientRect().top通过ref获取元素。使用 getBoundingClientRect().top 获取离顶部的距离  Vue无法读取HTMLCollection列表的length问题解决方案实践项目时候发现一个问题在mounted阶段,获取Element对象,console.l......
  • 如何在Vue3中使用事件总线实现跨组件通信?
    在复杂的前端开发中,组件之间的通信是必不可少的环节。而在Vue3中,事件总线(EventBus)是一种方便且高效的实现跨组件通信的方法。本文将详细介绍如何在Vue3项目中使用事件总线来实现跨组件通信,并提供实际示例代码,帮助你更好地掌握这一技能。什么是事件总线?事件总线(EventBus)......