中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

vue如何開發(fā)一個(gè)加載Button組件

本篇內(nèi)容介紹了“vue如何開發(fā)一個(gè)加載Button組件”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)公司科技有限公司專業(yè)互聯(lián)網(wǎng)基礎(chǔ)服務(wù)商,為您提供服務(wù)器托管,高防服務(wù)器租用,成都IDC機(jī)房托管,成都主機(jī)托管等互聯(lián)網(wǎng)服務(wù)。

vue如何開發(fā)一個(gè)加載Button組件

組件背景

點(diǎn)擊按鈕時(shí)請(qǐng)求一些接口數(shù)據(jù),而為了避免用戶重復(fù)的點(diǎn)擊我們通常會(huì)為這些按鈕添加loading。這個(gè)添加loading的功能本身時(shí)非常簡(jiǎn)單的,只要我們定義一個(gè)變量使用在Button組件中即可,但在做后臺(tái)管理類項(xiàng)目時(shí),這樣的按鈕可能會(huì)有非常非常多,可能一個(gè)組件中,很多變量都是xxx_loading,耗時(shí)耗力又不夠優(yōu)雅。

接下來,我們對(duì)Button組件做一個(gè)簡(jiǎn)單的封裝來解決這個(gè)耗時(shí)耗力又不夠優(yōu)雅的loading問題。

此時(shí),代碼如下:

asyncFunc() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, 2000)
  })
},
handleTestModal() {
  const that = this
  this.$confirm({
    title: '測(cè)試異步函數(shù)',
    content: '異步函數(shù)延遲兩秒結(jié)束',
    async onOk() {
      await that.asyncFunc()
    }
  })
},

看到這種效果后,就想到,如果可以封裝一個(gè)Button組件,將需要執(zhí)行的函數(shù)傳入,組件中自動(dòng)根據(jù)函數(shù)執(zhí)行情況添加loading效果豈不是非常的方便。

實(shí)現(xiàn)LoadingButton

定義組件參數(shù)

這邊就定義幾個(gè)大家會(huì)常用到的參數(shù):text(按鈕文字)、type(按鈕類型)asyncFunc(按鈕點(diǎn)擊時(shí)執(zhí)行的異步函數(shù))、delay(loading延遲),另外,還需要一個(gè)組件內(nèi)部的loading變量來控制我們Button組件的狀態(tài),代碼如下:

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組件進(jìn)行二次封裝

在我們的自定義LoadingButton組件中,將上面定義的參數(shù)使用起來,并綁定一個(gè)click事件,代碼如下:

<template>
  <Button :type="type" :loading="loading" @click="handleClick">
    {{ text }}
  </Button>
</template>

<script>
import { Button } from 'ant-design-vue'

export default {
    components: {
        Button
    },
    methods: {
        handleClick() {}
    }
}
</script>

判斷異步函數(shù)asyncFunc

這一部分為整個(gè)組件最重要的一個(gè)部分,即我們?nèi)绾稳ヅ袛鄠魅氲暮瘮?shù)是異步函數(shù),當(dāng)我們傳入的asyncFunc函數(shù)是異步函數(shù)時(shí),組件才需要添加loading的動(dòng)畫,那么我們應(yīng)該如何去判斷一個(gè)函數(shù)是否為異步函數(shù)呢?

參考antd是如何實(shí)現(xiàn)的?

上面我們剛介紹了antdModal對(duì)話框中有類似的邏輯,那么不妨去閱讀一下這部分相關(guān)的源碼,看下antd的實(shí)現(xiàn)方式:

// 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源碼的實(shí)現(xiàn),我們知道,判斷一個(gè)函數(shù)是否是異步函數(shù),可以通過判斷函數(shù)是否有.then(ret && ret.then)方法,那么我們也可以類似的做一個(gè)判斷,代碼如下:

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

  // 如果是異步函數(shù),則顯示loading
  if (ret && ret.then) {
    this.loading = {
      delay: this.delay
    }
    ret.finally(() => {
      this.loading = false
    })
  }
}

測(cè)試LoadingButton組件

到這里我們的最核心的組件邏輯就開發(fā)完成了,后面我們寫一個(gè)demo來測(cè)試一下這個(gè)LoadingButton組件是否符合預(yù)期:demo代碼如下:

<template>
  <div>
    <LoadingButton :delay="500" :asyncFunc="asyncFunc" />
  </div>
</template>

<script>
import LoadingButton from './LoadingButton.vue'

export default {
  data() {
    return {
      loading: false
    }
  },
  components: {
    LoadingButton
  },
  methods: {
    asyncFunc() {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve()
        }, 2000)
      })
    }
  }
}
</script>

符合之前的預(yù)期效果,這樣我們?cè)儆蓄愃菩枰?code>loading的場(chǎng)景時(shí),就可以直接使用LoadingButton組件,將點(diǎn)擊需要執(zhí)行的異步函數(shù)傳入即可,不需要再去定義loading變量。

寫在最后

這個(gè)組件其實(shí)核心的代碼非常少,也很容易讀懂。由于最近在做一些業(yè)務(wù)這類場(chǎng)景比較多,感覺這個(gè)小組件還是挺實(shí)用的所以分享給大家,這里也是只對(duì)最重要的部分做了一個(gè)介紹,相信大家學(xué)會(huì)了之后也可以通過這個(gè)方式封裝出符合自己實(shí)際場(chǎng)景需求的組件。最后,附上這個(gè)組件的完整代碼:

<template>
  <Button :type="type" :loading="loading" @click="handleClick">
    {{ text }}
  </Button>
</template>

<script>
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()

      // 如果是異步函數(shù),則顯示loading
      if (ret && ret.then) {
        this.loading = {
          delay: this.delay
        }
        ret.finally(() => {
          this.loading = false
        })
      }
    }
  }
}
</script>

“vue如何開發(fā)一個(gè)加載Button組件”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

本文標(biāo)題:vue如何開發(fā)一個(gè)加載Button組件
文章路徑:http://www.rwnh.cn/article40/psjdeo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、微信小程序App設(shè)計(jì)、營(yíng)銷型網(wǎng)站建設(shè)、用戶體驗(yàn)、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計(jì)公司
晋州市| 犍为县| 繁峙县| 徐水县| 定远县| 张掖市| 赫章县| 兴和县| 赤壁市| 阿坝县| 鄂伦春自治旗| 呼和浩特市| 绵竹市| 府谷县| 宜都市| 温泉县| 剑阁县| 炉霍县| 安仁县| 玛纳斯县| 瓦房店市| 灌阳县| 涟水县| 宝山区| 桦南县| 沙湾县| 汽车| 佛山市| 罗平县| 茌平县| 清丰县| 策勒县| 潮安县| 铜梁县| 宜宾市| 台北县| 望江县| 凯里市| 昌邑市| 固原市| 闻喜县|