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

 
 

posted on   &大飞  阅读(1305)  评论(0编辑  收藏  举报

编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示