Vue—插件之VueWait详解(转)
目录
一、概述
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 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)