站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        vue組件實戰(zhàn):開發(fā)一個加載Button組件–LoadingButton

        本篇文章手把手帶大家開發(fā)一個超實用的vue加載Button組件–LoadingButton,希望對大家有所幫助。

        vue組件實戰(zhàn):開發(fā)一個加載Button組件--LoadingButton

        組件背景

        在平時的工作中,經(jīng)常會遇到一個場景:

        vue組件實戰(zhàn):開發(fā)一個加載Button組件--LoadingButton

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

        接下來,我們對Button組件做一個簡單的封裝來解決這個耗時耗力又不夠優(yōu)雅的loading問題。(學(xué)習(xí)視頻分享:vue視頻教程)

        靈感來源

        我們在使用Antd的Modal對話框時,當(dāng)我們的onOk異步函數(shù)時,此時Modal的確定按鈕會自動添加loading效果,在函數(shù)執(zhí)行完成后關(guān)閉彈窗,就像這樣:

        vue組件實戰(zhàn):開發(fā)一個加載Button組件--LoadingButton

        此時,代碼如下:

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

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

        實現(xiàn)LoadingButton

        定義組件參數(shù)

        這邊就定義幾個大家會常用到的參數(shù):text(按鈕文字)type(按鈕類型)asyncFunc(按鈕點擊時執(zhí)行的異步函數(shù))delay(loading延遲),另外,還需要一個組件內(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ù)使用起來,并綁定一個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

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

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

        上面我們剛介紹了antdModal對話框中有類似的邏輯,那么不妨去閱讀一下這部分相關(guān)的源碼,看下antd的實現(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源碼的實現(xiàn),我們知道,判斷一個函數(shù)是否是異步函數(shù),可以通過判斷函數(shù)是否有.then(ret && ret.then)方法,那么我們也可以類似的做一個判斷,代碼如下:

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

        測試LoadingButton組件

        到這里我們的最核心的組件邏輯就開發(fā)完成了,后面我們寫一個demo來測試一下這個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>

        我們寫了一個異步函數(shù)asyncFunc用來模擬實際業(yè)務(wù)中的異步請求,現(xiàn)在可以看下效果:

        vue組件實戰(zhàn):開發(fā)一個加載Button組件--LoadingButton

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

        寫在最后

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

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

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

        作者:liangyue

        (學(xué)習(xí)視頻分享:web前端開發(fā)、編程基礎(chǔ)視頻)

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 麻豆国内精品欧美在线| 亚洲精品国产精品乱码在线观看| 精品福利一区二区三区| 99久久国产热无码精品免费| 一本大道无码日韩精品影视| 国产精品区AV一区二区| 国产成人精品日本亚洲直接| 一本一本久久A久久综合精品| 国产一区二区精品尤物| 91av国产精品| 国产伦精品一区二区三区女| 久久精品a亚洲国产v高清不卡 | 国产成人精品a视频一区 | 国产精品无码素人福利不卡| 久久久国产精品福利免费| 99精品国产在热久久无毒不卡| 少妇人妻偷人精品免费视频| 正在播放酒店精品少妇约| 免费视频成人国产精品网站| 国产一区二区三区欧美精品| 国产国拍亚洲精品福利| 成人国产精品动漫欧美一区 | 亚洲日韩精品一区二区三区| 欧美人与性动交α欧美精品| 黑人巨茎精品欧美一区二区| 国产精品亚洲高清一区二区| 99视频在线精品国自产拍亚瑟| 四虎影视国产精品永久在线| 久久久精品午夜免费不卡| 99久久成人国产精品免费| 99国产欧美精品久久久蜜芽| 国产精品无码一区二区三级| 国产精品日韩欧美一区二区三区 | 免费精品一区二区三区第35| 亚洲天堂久久精品| 国产成人精品一区在线| 国产精品亚洲专区无码WEB| 精品国产人成亚洲区| 久久青青草原精品国产软件| 日韩精品一区二区午夜成人版| 久久亚洲精品无码观看不卡|