首页 >

vue组件实战:开发一个加载Button组件–LoadingButton

web前端|Vue.jsvue组件实战:开发一个加载Button组件--LoadingButton
Vue,vue.js
web前端-Vue.js
本篇文章手把手带大家开发一个超实用的vue加载Button组件–LoadingButton,希望对大家有所帮助。
QQ机器人开源码,Ubuntu掉驱动,tomcat技术服务支持,爬虫神器插件,php发展前景怎么样,萧山区百度seo平台lzw
仿土巴兔源码模板,ubuntu坏道隔离方法,tomcat负载均衡架构图,小孩爬虫馆视频,写出php所有的基本变量类型,seo产品分析lzw
组件背景
php打卡考勤系统源码,tbook刷成Ubuntu,爬虫数据用于商业,php cform,顺德seo排名lzw
在平时的工作中,经常会遇到一个场景:

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

接下来,我们对Button组件做一个简单的封装来解决这个耗时耗力又不够优雅的loading问题。(学习视频分享:vue视频教学)

灵感来源

此时,代码如下:

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

实现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事件,代码如下:

  import { Button } from 'ant-design-vue'export default {    components: {        Button    },    methods: {        handleClick() {}    }}

判断异步函数asyncFunc

参考antd是如何实现的?

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

// components/modal/ActionButton.jsxonClick() {  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组件

  
import LoadingButton from './LoadingButton.vue'export default { data() { return { loading: false } }, components: { LoadingButton }, methods: { asyncFunc() { return new Promise(resolve => { setTimeout(() => { resolve() }, 2000) }) } }}

我们写了一个异步函数asyncFunc用来模拟实际业务中的异步请求,现在可以看下效果:

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

写在最后

  import { Button } from 'ant-design-vue'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: () => {}    }  },  components: {    Button  },  computed: {    isFunc() {      return typeof this.asyncFunc === 'function'    }  },  methods: {    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        })      }    }  }}

(学习视频分享:web前端开发、编程基础视频)


  • 暂无相关文章
  • Posted in 未分类