Vue—插件之VueWait詳解(轉)


https://github.com/f/vue-wait

目錄

一、概述

二、引入vue-wait組件

三、常見應用

四、拓展


一、概述

VueWait是一個復雜的裝載器和進度管理組件,常用於Vue、Vuex和Nuxt。VueWait可以幫助管理頁面上的多個加載狀態,狀態之間不會有任何沖突。

實現思路:通過管理具有多個加載狀態的數組(或者Vuex存儲),讓內置加載程序組件偵聽注冊的加載程序,並立即進入加載狀態。

二、引入VueWait組件

第一步:安裝

> npm i vue-wait

第二步:在main.js中全局注冊

import VueWait from 'vue-wait'

Vue.use(VueWait)

new Vue({
    wait: new VueWait()
})

三、常見應用

/**
 * Vuex模塊
 */
import api from '@/api/demo/index';
import axios from 'axios';

export const namespace = 'demo/index';

export const actions = {
    DEMOAC: 'demoac'
};

export default {
    namespaced: true,
    state,
    mutations,
    actions: {
        [actions.DEMOAC](context) {
            return axios.post(''); 
            // return不能省略, 必須返回一個Promise對象, 否則該例中的加載器無效
        }
    }
};
<template>
    <el-table v-loading="$wait.is('jpf-loading')"></el-table>
</template>
<script>
    // 引入vue-wait
    import { mapWaitingActions } from 'vue-wait';
    // 引入store的命名空間
    import { namespace, actions  } from '@/store/index';

    export default{
        mounted(){
            this.getList();
        },
        methods: {
            // namespace為Vuex模塊名稱, 不能隨便寫
            // 如果vuex不區分模塊, 可省略
            ...mapWaitingActions(namespace, {
                getList: {
                    // 屬性值為字符串, 指向Vuex模塊中actions里面的方法
                    action: actions.demoac,
                    // 自定義加載器名稱
                    loader: 'jpf-loading'
                },
                getMsg: { 
                    // ... 
                }
            });
        }
    };
</script>

注意,如果VueWait是全局配置的,則啟動的加載器可在任意組件使用。

四、拓展

拓展1:VueWait的默認屬性配置

new Vue({
    render: h => h(App),
    wait: new VueWait({
        // 默認值如下
        useVuex: false, // 使用Vuex管理等待狀態
        vuexModuleName: 'wait', // 默認的Vuex模塊名稱

        registerComponent: true, // 注冊v-wait組件
        componentName: 'v-wait', // <v-wait>組件名稱, 可自定義

        registerDirective: true, // 注冊v-wait指令 
        directiveName: 'wait' // <span v-wait />偽指令名稱, 可自定義
    })
}).$mount('#app')

拓展2:使用Vuex管理等待狀態

全局注冊時,將useVuex配置項設置為true,即可使用Vuex管理等待狀態。

import VueWait from 'vue-wait'

Vue.use(VueWait)

new Vue({
    wait: new VueWait({
        useVuex: true,
        vuexModuleName: 'vuex-example-module' // Vuex模塊名稱, 可選的, 默認為'wait'
    })
})

拓展3:VueWait選項

可以使用如下配置項,自定義VueWait的行為。

選項名稱 類型 默認 描述
accessorName String "$wait" 設置訪問器名稱,可更改
useVuex Boolean false 是否啟用與Vuex組件的集成,若啟用則v-wait組件和指令禁用
vuexModuleName String "wait" Vuex模塊名稱
registerComponent Boolean true 注冊v-wait組件
componentName String "v-wait" 更改v-wait組件名稱
registerDirective Boolean true 注冊v-wait指令
directiveName String "v-wait" 更改v-wait指令名稱

拓展4:全局模板屬性

VueWait提供了一些全局模板屬性,可通過$wait訪問,功能如下所示。

.any

任意加載器啟動,返回true,沒有任何加載器啟動時,返回false。

<template>
    <div v-if="$wait.any">加載中...</div>
    <button @click="$wait.start('loader')">啟動加載器</button>
    <button @click="$wait.end('loader')">關閉加載器</button>
</template>

.is(loader String | Matcher) / .waiting(loader String | Matcher)

啟動指定加載器時,返回true,否則返回false。注意,可以使用matcher匹配器使代碼更靈活。

<template>
    <div v-if="$wait.is('loader')">加載中...</div>
    <button @click="$wait.start('loader')">啟動加載器</button>
    <button @click="$wait.end('loader')">關閉加載器</button>
</template>
<template>
    <!-- 使用matcher匹配器 -->
    <div v-if="$wait.is('loader.*')">加載中......</div>
</template>

.is(loader Array<String | Matcher>) 或 .waiting(loader Array<String | Matcher>)

數組中包含的任意加載器啟動,返回true,否則返回false。注意,可以使用matcher匹配器使代碼更靈活。

<template>
    <div v-if="$wait.is(['loader1', 'loader2'])">sdfd</div>
</template>

.start(loader String)、.end(loader String)

啟動/關閉指定加載器。

<template>
    <div>
        <button @click="$wait.start('jpf')">啟動加載器</button>
        <button @click="$wait.end('jpf')">關閉加載器</button>
        <div v-if="$wait.is('jpf')">loading......</div>
    </div>
</template>

.progress(loader String, current [, total = 100])

設置指定加載器的進度。current表示當前進度,totle表示總量。

<template>
    <div>
        <progress min="0" max="100" :value="$wait.percent('downloading')"/>
        <button @click="$wait.progress('downloading', 10)">Set progress to 10</button>
        <button @click="$wait.progress('downloading', 50)">Set progress to 50</button>
        <button @click="$wait.progress('downloading', 50, 200)">
            Set progress to 50 of 200 (25%)
        </button>
    </div>
</template>

.percent(loader String)

返回指定加載器的百分比。

<template>
    <progress min="0" max="100" :value="$wait.percent('downloading')"/>
</template>

拓展5:指令

使用指令可以使模板更簡潔,如下是一些指令的用法。

v-wait:visible="'loader String'"

指定加載器啟動,返回true,關閉返回false。

<template>
    <div>
        <button @click="$wait.start('jpf')">啟動加載器</button>
        <button @click="$wait.end('jpf')">關閉加載器</button>
        <div v-wait:visible="'jpf'">加載中......</div>
    </div>
</template>

v-wait:hidden="'loader String'" 或 v-wait:visible.not="'loader String'"

指定加載器關閉,返回true,啟動返回false。

<template>
    <div>
        <button @click="$wait.start('jpf')">啟動加載器</button>
        <button @click="$wait.end('jpf')">關閉加載器</button>
        <div v-wait:hidden="'jpf'">加載中......</div>
    </div>
</template>

v-wait:disabled="'loader String'"

指定加載器啟動,則給當前元素標簽添加disabled特性,否則移除disabled特性。

<template>
    <div>
        <button @click="$wait.start('jpf')">啟動加載器</button>
        <button @click="$wait.end('jpf')">關閉加載器</button>
        <input v-wait:disabled="'jpf'" placeholder="測試" />
        <!-- 使用*匹配器 -->
        <input v-wait:disabled="'*'" placeholder="測試" />
    </div>
</template>

v-wait:enabled="'loader String'" 或 v-wait:disabled.not="'loader String'"

指定加載器啟動,則給當前元素標簽移除disabled特性,否則添加disabled特性。

<template>
    <div>
        <button @click="$wait.start('jpf')">啟動加載器</button>
        <button @click="$wait.end('jpf')">關閉加載器</button>
        <input v-wait:enabled="'jpf'" placeholder="測試" />
        <input v-wait:disabled.not="'jpf'" placeholder="測試" />
    </div>
</template>

v-wait:click.start="'loader String'"、v-wait:click.end="'loader String'"

單擊啟動/關閉指定加載器。

<template>
    <div>
        <button v-wait:click.start="'jpf'">啟動加載器</button>
        <button v-wait:click.end="'jpf'">關閉加載器</button>
        <input v-wait:disabled="'jpf'" placeholder="測試" />
    </div>
</template>

v-wait:toggle="'loader String'"

單擊時切換指定加載器的狀態。

<template>
    <div>
        <button v-wait:toggle="'jpf'">切換加載器</button>
        <input v-wait:disabled="'jpf'" placeholder="測試" />
    </div>
</template>

v-wait:click.progress="['loader String', 80]"

單擊時設置指定加載器的進度。

<template>
    <div>
        <progress min="0" max="100" :value="$wait.percent('downloading')" />
        <button v-wait:click.progress="['downloading', 80]">設置加載進度</button>
    </div>
</template>

拓展6:action映射器和getter映射器

VueWait提供了action映射器和getter映射器來配合Vuex使用。action映射器有兩個參數。其一為vuex的模塊名,如果vuex沒有區分模塊,可省略,其二為wait配置。

假設有一個名為getList的異步操作,它將調用映射的方法,並在解析動作時啟動加載器。

/**
 * vuex代碼
 */
actions: {
    getList() {
        return axios.post(postApi);
    }
}
// return不能省略, 必須返回一個Promise對象, 否則action映射器中設置的加載器無效
<template>
    <div>
        <button @click="getList">Set progress to 10</button>
        <p v-if="$wait.is('jpfLoader')">加載中.....</p>
        <p v-if="$wait.is('demoloader')">加載中.....</p>
    </div>
</template>
<script>
import { mapWaitingActions, mapWaitingGetters } from 'vue-wait'

export default {
    computed: {
        ...mapWaitingGetters({
            demoloader: 'jpfLoader'
        })
        // mapWaitingGetters將加載器映射到自定義變量名
    },
    methods: {
        ...mapWaitingActions({
            getList: 'jpfLoader'
        })
        // key值表示vuex中action方法名, 不能自定義
        // value值為自定義加載器(不用mapWaitingGetters映射, 也可以直接使用)
    }
}
</script>

還可以將vuex的action操作映射到自定義方法,並自定義加載器名稱,代碼如下所示。

<template>
    <div>
        <button @click="fn">測試</button>
        <p v-if="$wait.is('jpfLoader')">加載中.....</p>
    </div>
</template>

<script>
import { mapWaitingActions } from 'vue-wait';

export default{
    methods: {
        ...mapWaitingActions({
            fn: {
                action: 'getList',
                loader: 'jpfLoader'
            }
        })
    }
}
</script>

action映射器的第二個參數也可以是數組,如下代碼所示。

<template>
    <div>
        <button @click="demo">Set progress to 10</button>
        <p>{{$wait.is('demoloader')}}</p>
    </div>
</template>
<script>
import { mapWaitingActions } from 'vue-wait'

export default {
    methods: {
        ...mapWaitingActions([
            // 將vuex方法映射到自定義方法名, 並設置自定義加載器名
            { method: 'demo1', action: 'getList1', loader: 'demoloader1' },
            { method: 'demo2', action: 'getList2', loader: 'demoloader2' }
        ])
    }
}
</script>

拓展7:waitFor(loader String,func Function[,forceSync = false])

waitFor可以用來包裝函數。第一個參數為加載器,調用包裝函數時啟動加載器。第二個參數為原始函數,原始函數加載完成后關閉加載器。

默認情況下,waitFor返回的是異步函數。如果需要返回同步函數,只須將最后一個參數設置為true。注意,最后一個參數設置為true后,加載器會失效。

<template>
    <div>
        <button @click="fetchDataFromApi">Set progress to 10</button>
        <p>{{$wait.is('demoloader')}}</p>
    </div>
</template>
<script>
import { waitFor } from 'vue-wait'

export default {
    methods: {
        fetchDataFromApi: waitFor('demoloader', () => {
            return new Promise(resolve => setTimeout(resolve, 500));
            // return 不能省略, 且必須返回Promise對象, 否則加載器無效
        })
    }
}
</script>

拓展8:v-wait組件

啟用

VueWait默認啟用v-wait組件,如下代碼所示。

import VueWait from 'vue-wait'

Vue.use(VueWait)

new Vue({
    wait: new VueWait({
        registerComponent: true // 默認值, 啟動v-wait組件
    })
})

如果將配置項registerComponent設置為false,則禁用v-wait組件,此時可以通過手動導入的方式繼續使用該組件。

new Vue({
    wait: new VueWait({
        registerComponent: false// 禁用v-wait組件
    })
})
<script>
// 手動導入v-wait組件
import vLoading from 'vue-wait/src/components/v-wait.vue'

export default {
    components: {
        'v-wait': vLoading
    }
}
</script>

應用

<template>
    <div>
        <!-- loader是加載器名稱, 對應v-wait標簽的for特性 -->
        <button @click="$wait.start('loader')">啟動加載器</button>
        <button @click="$wait.end('loader')">關閉加載器</button>
        <v-wait for="loader">
            <!-- 插槽名稱不能更改, template標簽可以換成其它 -->
            <template slot="waiting">
                <div>
                    啟動加載器時展示
                </div>
            </template>
            <div>關閉加載器時顯示</div>
        </v-wait>
    </div>
</template>
<!-- 按鈕點擊后加載狀態設置 -->
<template>
    <button
        :disabled='$wait.is("loader")'
        @click="$wait.start('loader')"
    >
        <v-wait for='loader'>
            <template slot='waiting'>加載中...</template>
            按鈕
        </v-wait>
    </button>
</template>

拓展9:v-wait組件和可以與其它組件庫搭配使用

只須將slot='waiting'添加到對應組件,vue即可處理其余工作。

import { OrbitSpinner } from 'epic-spinners';
Vue.component('orbit-spinner', OrbitSpinner);
<v-wait for='something to load'>
    <orbit-spinner
        slot='waiting'
        :animation-duration="1500"
        :size="64"
        :color="'#ff1d5e'"
    />
</v-wait>

還可以使用其它的組件庫:https://github.com/vuejs/awesome-vue#loader

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM