中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue如何開發一個加載Button組件

發布時間:2022-05-24 09:05:39 來源:億速云 閱讀:245 作者:zzz 欄目:編程語言

本篇內容介紹了“vue如何開發一個加載Button組件”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

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事件,代碼如下:

<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>

判斷異步函數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代碼如下:

<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>

符合之前的預期效果,這樣我們再有類似需要loading的場景時,就可以直接使用LoadingButton組件,將點擊需要執行的異步函數傳入即可,不需要再去定義loading變量。

寫在最后

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

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

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

“vue如何開發一個加載Button組件”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

诏安县| 龙川县| 上蔡县| 饶阳县| 扶余县| 中牟县| 南康市| 柳河县| 元朗区| 漯河市| 密山市| 尼玛县| 龙游县| 玉溪市| 和龙市| 常德市| 凉城县| 黄山市| 开封县| 永胜县| 卓尼县| 昌平区| 苏尼特右旗| 武宁县| 崇仁县| 廉江市| 新密市| 古蔺县| 开江县| 咸丰县| 辽宁省| 日土县| 新兴县| 巴林左旗| 山阳县| 武山县| 浦北县| 嵊泗县| 平昌县| 黑龙江省| 东源县|