• 【elementui】处理多个按钮的 loading 状态


    问题

    因为业务要求,每个按钮点击时都要一个加载状态。我们知道使用 elementui 的 button 可以用 loading 变量,现在问题在于,如果一个页面有多少个按钮,就必须维护多少个 loading 变量,这样容易导致代码臃肿不易维护。

    思路

    事件委托(可行,不推荐)

    需要给每个按钮加一个标志,同时需要额外的代码来判断点击事件来自哪个按钮。

    网络请求拦截(不可行)

    设想利用 axios 的拦截点击按钮发起的网络请求,但是我们无法知道点击事件来自哪个按钮,也无法控制按钮的 loading 结束状态。

    扩展按钮组件(可行,推荐)

    思路就是扩展 elementui 按钮组件,给每个按钮单独维护一个 loading 状态。

    扩展按钮组件

    自定义组件
    import { Button } from "element-ui";
    
    export default {
      name: 'el-button-custom',
      extends: Button, // 扩展 elementui 的按钮组件
      data() {
        return {
          isLoading: false,
        }
      },
      render(h) {
        return h(Button, {
          class: 'my-class',
          attrs: this.$attr,
          on: {
            click: this.onClick // 绑定事件
          },
          props: {
            // 传入 Button 定义的参数(这里的参数都扩展自 Button,所以不需要自己声明)
            ...this.$props, 
            // 传入需要维护的 loading 变量
            loading: this.isLoading,
          }
        }, this.$slots.default)
      },
      methods: {
        // 自定义绑定事件控制 loading 状态
        onClick() {
          let res = this.$listeners.click() // 调用事件处理函数
          // 注意:事件处理函数必须返回一个 Promise 实例
          if(res instanceof Promise) { 
            this.isLoading = true
            res.finally(() => {
              this.isLoading = false // 结束加载状态
            })
          }else { // 错误提示
            throw Error('@click function should return a Promise instance.')
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    注册
    Vue.component('el-button-custom', ElButtonCustom)
    
    • 1
    使用
    <template>
    	<el-button-custom @click="onButton1">转账</<el-button-custom>
    	<el-button-custom @click="onButton2">交易</<el-button-custom>
    	<el-button-custom @click="onButton3">同步</<el-button-custom>
    </template>
    export default {
    	methods: {
    		async onButton1() { // 声明为 async
    		},
    		onButton2() { 
    			return Promise.resolve(0) // 显式返回 Promise 实例
    		},
    		onButton3() { 
    			return new Promise(resovle => resolve(0)) // 显式返回 Promise 实例
    				.then(() => {})
    		},
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    无需公网IP,在家SSH远程连接公司内网服务器「cpolar内网穿透」
    分享Markdown编写文档的技巧
    Roson的Qt之旅 #113 QML布局之StackLayout(堆栈布局)
    SQL完整性约束
    【Kotlin精简】第7章 泛型
    【随想】每日两题Day.4
    java后端开发面试准备(1)-Redis缓存
    Elasticsearch对于大数据量(上亿量级)的聚合如何实现?
    Sharding-Jdbc分库分表集成Mybatis-Plus+多数据源管理
    WPF引入 ttf 图标文件使用记录
  • 原文地址:https://blog.csdn.net/u012557814/article/details/126886758