目錄
元件背景
靈感來源
實作LoadingButton
写在最后
首頁 web前端 Vue.js vue元件實戰:開發一個載入Button元件--LoadingButton

vue元件實戰:開發一個載入Button元件--LoadingButton

May 23, 2022 pm 08:24 PM
vue vue.js

這篇文章手把手帶大家開發一個超實用的vue載入Button元件--LoadingButton,希望對大家有幫助。

vue元件實戰:開發一個載入Button元件--LoadingButton

元件背景

在平常的工作中,常常會遇到一個場景:

vue元件實戰:開發一個載入Button元件--LoadingButton

#點擊按鈕時請求一些介面數據,而為了避免用戶重複的點擊我們通常會為這些按鈕添加loading。這個新增loading的功能本身時非常簡單的,只要我們定義一個變數使用在Button元件中即可,但在做後台管理類別專案時,這樣的按鈕可能會有非常非常多,可能一個元件中,很多變數都是xxx_loading,耗時耗力又不夠優雅。

接下來,我們對Button元件做一個簡單的封裝來解決這個耗時耗力又不夠優雅的loading問題。 (學習影片分享:vue影片教學

靈感來源

我們在使用AntdModal對話方塊時,當我們的onOk非同步函數時,此時Modal的確定按鈕會自動新增loading 效果,在函數執行完成後關閉彈窗,就像這樣:

vue元件實戰:開發一個載入Button元件--LoadingButton

#此時,程式碼如下:

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<span style="font-size: 18px;"></span>中的Button<span style="font-size: 18px;"></span>元件進行二次封裝

在我們的自訂

LoadingButton元件中,將上面定義的參數使用起來,並綁定一個click事件,程式碼如下:

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

<script>
import { Button } from &#39;ant-design-vue&#39;

export default {
    components: {
        Button
    },
    methods: {
        handleClick() {}
    }
}
</script>
登入後複製

判斷非同步函數asyncFunc<span style="font-size: 18px;"></span>

##這一部分為整個元件最重要的一個部分,即我們如何去判斷傳入的函數是非同步函數,當我們傳入的
asyncFunc

函數是非同步函數時,元件需要添加loading的動畫,那麼我們應該如何去判斷一個函數是否為非同步函數呢?

參考

antd是如何實現的? 上面我們剛剛介紹了

antd

Modal對話方塊中有類似的邏輯,那麼不妨去閱讀這部分相關的源碼,看看antd的實作方式:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// 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 &amp;&amp; ret.then) { this.setState({ loading: true }); ret.then( (...args) =&gt; { // It&amp;#39;s unnecessary to set loading=false, for the Modal will be unmounted after close. // this.setState({ loading: false }); closeModal(...args); }, e =&gt; { // 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(); } },</pre><div class="contentsignin">登入後複製</div></div>閱讀

antd

原始碼的實現,我們知道,判斷一個函數是否是非同步函數,可以透過判斷函數是否有 .then(ret && ret.then)方法,那麼我們也可以類似的做一個判斷,程式碼如下:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>async handleClick() { const asyncFunc = this.asyncFunc if (!this.isFunc) { return } const ret = asyncFunc() // 如果是异步函数,则显示loading if (ret &amp;&amp; ret.then) { this.loading = { delay: this.delay } ret.finally(() =&gt; { this.loading = false }) } }</pre><div class="contentsignin">登入後複製</div></div>

測試

LoadingButton元件

到這裡我們的最核心的元件邏輯就開發完成了,後面我們寫一個demo來測試一下這個
LoadingButton

元件是否符合預期:demo程式碼如下:

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

<script>
import LoadingButton from &#39;./LoadingButton.vue&#39;

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

我們寫了一個非同步函數
asyncFunc

用來模擬實際業務中的非同步請求,現在可以看效果:

vue元件實戰:開發一個載入Button元件--LoadingButton#符合先前的預期效果,這樣我們再有類似需要

loading

的場景時,就可以直接使用LoadingButton元件,將點擊需要執行的非同步函數傳入即可,不需要再去定義loading變數。

写在最后

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

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

<script>
import { Button } from &#39;ant-design-vue&#39;

export default {
  data() {
    return {
      loading: false
    }
  },
  props: {
    text: {
      type: String,
      default: &#39;确定&#39;
    },
    type: {
      type: String,
      default: &#39;primary&#39;
    },
    delay: {
      type: Number,
      default: 0
    },
    asyncFunc: {
      type: Function,
      default: () => {}
    }
  },
  components: {
    Button
  },
  computed: {
    isFunc() {
      return typeof this.asyncFunc === &#39;function&#39;
    }
  },
  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>
登入後複製

原文地址:https://juejin.cn/post/7099234795720278046

作者:liangyue

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

以上是vue元件實戰:開發一個載入Button元件--LoadingButton的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vue.js vs.反應:特定於項目的考慮因素 vue.js vs.反應:特定於項目的考慮因素 Apr 09, 2025 am 12:01 AM

Vue.js適合中小型項目和快速迭代,React適用於大型複雜應用。 1)Vue.js易於上手,適用於團隊經驗不足或項目規模較小的情況。 2)React的生態系統更豐富,適合有高性能需求和復雜功能需求的項目。

vue怎麼給按鈕添加函數 vue怎麼給按鈕添加函數 Apr 08, 2025 am 08:51 AM

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

vue多頁面開發是啥意思 vue多頁面開發是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

vue遍歷怎麼用 vue遍歷怎麼用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。

vue的div怎麼跳轉 vue的div怎麼跳轉 Apr 08, 2025 am 09:18 AM

Vue 中 div 元素跳轉的方法有兩種:使用 Vue Router,添加 router-link 組件。添加 @click 事件監聽器,調用 this.$router.push() 方法跳轉。

vue怎麼a標籤跳轉 vue怎麼a標籤跳轉 Apr 08, 2025 am 09:24 AM

實現 Vue 中 a 標籤跳轉的方法包括:HTML 模板中使用 a 標籤指定 href 屬性。使用 Vue 路由的 router-link 組件。使用 JavaScript 的 this.$router.push() 方法。可通過 query 參數傳遞參數,並在 router 選項中配置路由以進行動態跳轉。

React與Vue:Netflix使用哪個框架? React與Vue:Netflix使用哪個框架? Apr 14, 2025 am 12:19 AM

NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVuedIrectly.1)TeamSperience:selectBasedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects:reactforforforproproject,reactforforforcompleplexones.3)cocatizationneedneeds:reactoffipicatizationneedneedneedneedneedneeds:reactoffersizationneedneedneedneedneeds:reactoffersizatization needefersmoreflexibleise.4)

vue組件傳值是什麼意思 vue組件傳值是什麼意思 Apr 07, 2025 pm 11:51 PM

Vue 組件傳值是一種在組件之間傳遞數據和信息的機制。它可以通過屬性 (props) 或事件 (events) 實現:屬性 (props):聲明要在組件中接收的數據,在父組件中傳遞數據。事件 (events):使用 $emit 方法觸發事件,並使用 v-on 指令在父組件中監聽。

See all articles