vue如何开发一个加载Button组件

本篇内容介绍了“vue如何开发一个加载Button组件”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

创新互联公司科技有限公司专业互联网基础服务商,为您提供服务器托管高防服务器租用,成都IDC机房托管,成都主机托管等互联网服务。

vue如何开发一个加载Button组件

组件背景

点击按钮时请求一些接口数据,而为了避免用户重复的点击我们通常会为这些按钮添加loading。这个添加loading的功能本身时非常简单的,只要我们定义一个变量使用在Button组件中即可,但在做后台管理类项目时,这样的按钮可能会有非常非常多,可能一个组件中,很多变量都是xxx_loading,耗时耗力又不够优雅。

接下来,我们对Button组件做一个简单的封装来解决这个耗时耗力又不够优雅的loading问题。

此时,代码如下:

asyncFunc() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, 2000)
  })
},
handleTestModal() {
  const that = this
  this.$confirm({
    title: '测试异步函数',
    content: '异步函数延迟两秒结束',
    async onOk() {
      await that.asyncFunc()
    }
  })
},

看到这种效果后,就想到,如果可以封装一个Button组件,将需要执行的函数传入,组件中自动根据函数执行情况添加loading效果岂不是非常的方便。

实现LoadingButton

定义组件参数

这边就定义几个大家会常用到的参数:text(按钮文字)type(按钮类型)asyncFunc(按钮点击时执行的异步函数)delay(loading延迟),另外,还需要一个组件内部的loading变量来控制我们Button组件的状态,代码如下:

export default {
    data() {
        return {
          loading: false
        }
    },
    props: {
        text: {
          type: String,
          default: '确定'
        },
        type: {
          type: String,
          default: 'primary'
        },
        delay: {
          type: Number,
          default: 0
        },
        asyncFunc: {
          type: Function,
          default: () => {}
        }
    },
}

使用antd中的Button组件进行二次封装

在我们的自定义LoadingButton组件中,将上面定义的参数使用起来,并绑定一个click事件,代码如下:



判断异步函数asyncFunc

这一部分为整个组件最重要的一个部分,即我们如何去判断传入的函数是异步函数,当我们传入的asyncFunc函数是异步函数时,组件才需要添加loading的动画,那么我们应该如何去判断一个函数是否为异步函数呢?

参考antd是如何实现的?

上面我们刚介绍了antdModal对话框中有类似的逻辑,那么不妨去阅读一下这部分相关的源码,看下antd的实现方式:

// components/modal/ActionButton.jsx

onClick() {
  const { actionFn, closeModal } = this;
  if (actionFn) {
    let ret;
    if (actionFn.length) {
      ret = actionFn(closeModal);
    } else {
      ret = actionFn();
      if (!ret) {
        closeModal();
      }
    }
    if (ret && ret.then) {
      this.setState({ loading: true });
      ret.then(
        (...args) => {
          // It's unnecessary to set loading=false, for the Modal will be unmounted after close.
          // this.setState({ loading: false });
          closeModal(...args);
        },
        e => {
          // Emit error when catch promise reject
          // eslint-disable-next-line no-console
          console.error(e);
          // See: https://github.com/ant-design/ant-design/issues/6183
          this.setState({ loading: false });
        },
      );
    }
  } else {
    closeModal();
  }
},

阅读antd源码的实现,我们知道,判断一个函数是否是异步函数,可以通过判断函数是否有.then(ret && ret.then)方法,那么我们也可以类似的做一个判断,代码如下:

async handleClick() {
  const asyncFunc = this.asyncFunc
  if (!this.isFunc) {
    return
  }
  const ret = asyncFunc()

  // 如果是异步函数,则显示loading
  if (ret && ret.then) {
    this.loading = {
      delay: this.delay
    }
    ret.finally(() => {
      this.loading = false
    })
  }
}

测试LoadingButton组件

到这里我们的最核心的组件逻辑就开发完成了,后面我们写一个demo来测试一下这个LoadingButton组件是否符合预期:demo代码如下:



符合之前的预期效果,这样我们再有类似需要loading的场景时,就可以直接使用LoadingButton组件,将点击需要执行的异步函数传入即可,不需要再去定义loading变量。

写在最后

这个组件其实核心的代码非常少,也很容易读懂。由于最近在做一些业务这类场景比较多,感觉这个小组件还是挺实用的所以分享给大家,这里也是只对最重要的部分做了一个介绍,相信大家学会了之后也可以通过这个方式封装出符合自己实际场景需求的组件。最后,附上这个组件的完整代码:



“vue如何开发一个加载Button组件”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!


分享文章:vue如何开发一个加载Button组件
转载源于:http://ybzwz.com/article/psjdeo.html