千家信息网

怎么写一个即插即用的Vue Loading插件

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇"怎么写一个即插即用的Vue Loading插件"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一
千家信息网最后更新 2026年11月02日怎么写一个即插即用的Vue Loading插件

这篇"怎么写一个即插即用的Vue Loading插件"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"怎么写一个即插即用的Vue Loading插件"文章吧。

从使用方式说起

不管从0开始写起还是直接下载的Loading插件,都会抽象为一个组件,在用到的时候进行加载Loading,或者通过API手动进行show或者hide

...this.$wait.show()await fetch('http://example.org')this.$wait.hide()

或者通过Loading状态进行组件间的切换

。要想注册成全局状态,还需要给axios类的网络请求包添加拦截器,然后设置一个全局Loading状态,每次有网络请求或者根据已经设置好的URL将Loading状态设置为加载,请求完成后在设置为完成。

注册axios拦截器:

 let loadingUrls = [  `${apiUrl}/loading/`,  `${apiUrl}/index/`,  `${apiUrl}/comments/`,  ... ] axios.interceptors.request.use((config) => {  let url = config.url  if (loadingUrls.indexOf('url') !== -1) {   store.loading.isLoading = true  } })  axios.interceptors.response.use((response) => {  let url = response.config.url  if (loadingUrls.indexOf('url') !== -1) {   store.loading.isLoading = false  } })

使用时在每个组件下获取出loading状态,然后判断什么时候显示loading,什么时候显示真正的组件。

 

在当前页面下只有一个需要Loading的状态时使用良好,但如果在同一个页面下有多个不同的组件都需要Loading,你还需要根据不同组件进行标记,好让已经加载完的组件不重复进入Loading状态...随着业务不断增加,重复进行的Loading判断足以让人烦躁不已...

整理思路

Loading的核心很简单,就是请求服务器时需要显示Loading,请求完了再还原回来,这个思路实现起来并不费力,只不过使用方式上逃不开上面的显式调用的方式。顺着思路来看,能进行Loading设置的地方有,

  • 设置全局拦截,请求开始前设置状态为加载。

  • 设置全局拦截,请求结束后设置状态为完成。

  • 在触发请求的函数中进行拦截,触发前设置为加载,触发后设置为完成。

  • 判断请求后的数据是否为非空,如果非空则设置为完成

最终可以实现的情况上,进行全局拦截设置,然后局部的判断是最容易想到也是最容易实现的方案。给每个触发的函数设置before和after看起来美好,但实现起来简直是灾难,我们并没有before和after这两个函数钩子来告诉我们函数什么时候调用了和调用完了,自己实现吧坑很多,不实现吧又没得用只能去原函数里一个个写上。只判断数据局限性很大,只有一次机会。

既然是即插即用的插件,使用起来就得突出一个简单易用,基本思路上也是使用全局拦截,但局部判断方面与常规略有不同,使用数据绑定(当然也可以再次全局响应拦截),咱们实现起来吧~。

样式

Loading嘛,必须得有一个转圈圈才能叫Loading,样式并不是这个插件的最主要的,这里直接用CSS实现一个容易实现又不显得很糙的:

...

固定大小50px的正方形,使用border-radius把它盘得圆润一些,border设置个进度条底座,border-left-color设置为进度条好了。

演示地址

绑定数据与URL

提供外部使用接口

上面思路中提到,这个插件是用全局拦截与数据绑定制作的:

  • 暴露一个 source 属性,从使用的组件中获取出要绑定的数据。

  • 暴露一个 urls 属性,从使用的组件中获取出要拦截的URL。

不用关心source是什么类型的数据,我们只需要监控它,每次变化时都将Loading状态设置为完成即可,urls我们稍后再来完善它。

设置请求拦截器

拦截器中需要的操作是将请求时的每个URL压入一个容器内,请求完再把它删掉。

Vue.prototype.__loader_checks = []Vue.prototype.$__loadingHTTP = new Proxy({}, {  set: function (target, key, value, receiver) {    let oldValue = target[key]    if (!oldValue) {      Vue.prototype.__loader_checks.forEach((func) => {        func(key, value)      })    }    return Reflect.set(target, key, value, receiver)  }})axios.interceptors.request.use(config => {  Vue.prototype.$__loadingHTTP[config.url] = config   return config})axios.interceptors.response.use(response => {  delete Vue.prototype.$__loadingHTTP[response.config.url]   return response})

将其挂载在Vue实例上,方便我们之后进行调用,当然还可以用Vuex,但此次插件要突出一个依赖少,所以Vuex还是不用啦。

直接挂载在Vue上的数据不能通过computed或者watch来监控数据变化,咱们用Proxy代理拦截set方法,每当有请求URL压入时就做点什么事。Vue.prototype.__loader_checks用来存放哪些实例化出来的组件订阅了请求URL时做加载的事件,这样每次有URL压入时,通过Proxy来分发给订阅过得实例化Loading组件。

订阅URL事件

每一个都是一个崭新的实例,所以直接在mounted里订阅URL事件即可,只要有传入urls,就对__loader_checks里每一个订阅的对象进行发布,Loader实例接受到发布后会判断这个URL是否与自己注册的对应,对应的话会将自己的状态设置回加载,URL请求后势必会引起数据的更新,这时我们上面监控的source就会起作用将加载状态设置回完成。

使用槽来适配原来的组件

写完上面这些你可能有些疑问,怎么将Loading时不应该显示的部分隐藏呢?答案是使用槽来适配,

还是通过isLoading判断,如果处于加载那显示转圈圈,否则显示的是父组件里传入的槽,
这里写的要注意,Vue这里有一个奇怪的BUG,

  

在有时,如果同级的标签同时出现v-if与CSS选择器且样式是scoped,那用CSS选择器设置的样式将会丢失,

如果没有设置key那.loading的样式会丢失,除了设置key还可以把它变成嵌套的
。

注册成插件

Vue中的插件有四种注册方式,这里用mixin来混入到每个实例中,方便使用,同时我们也把上面的axios拦截器也注册在这里。

import axiosimport Loader from './loader.vue'export default {  install (Vue, options) {    Vue.prototype.__loader_checks = []    Vue.prototype.$__loadingHTTP = new Proxy({}, {      set: function (target, key, value, receiver) {        let oldValue = target[key]        if (!oldValue) {          Vue.prototype.__loader_checks.forEach((func) => {            func(key, value)          })        }            return Reflect.set(target, key, value, receiver)      }    })        axios.interceptors.request.use(config => {      Vue.prototype.$__loadingHTTP[config.url] = config           return config    })        axios.interceptors.response.use(response => {      delete Vue.prototype.$__loadingHTTP[response.config.url]           return response    })    Vue.mixin({      beforeCreate () {        Vue.component('v-loader', Loader)            }    })      } }

使用

在入口文件中使用插件

import Loader from './plugins/loader/index.js'...Vue.use(Loader)...

任意组件中无需导入即可使用

 
{{ msg }}

根据绑定的数据和绑定的URL自动进行Loading的显示与隐藏,无需手动设置isLoading是不是该隐藏,也不用调用show与hide在请求的方法里打补丁。

其他

上面的通过绑定数据来判断是否已经响应,如果请求后的数据不会更新,那你也可以直接在axios的response里做拦截进行订阅发布模式的响应。

以上就是关于"怎么写一个即插即用的Vue Loading插件"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

组件 数据 状态 插件 全局 实例 订阅 内容 函数 思路 样式 拦截器 方式 时候 不同 不用 事件 还是 面的 监控 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡网 什么是科技互联网 广东猪兼强互联网科技有限公司 西安纸贵互联网科技有限公司 科技互联网公司装修 汇久创客互联网科技 猫创互联网科技 互联网科技公司做什么 滨湖区互联网智能科技产品供应 用友工业互联网科技发展 济南有互联网科技公司吗 上海钢联属于互联网科技股吗 广州富喜互联网络科技 启辰互联网科技 广州互联网高科技取餐柜 广州梦谷互联网科技有限公司领导 容联科技互联网电商 互联网科技收购价值 恒生科技指数 中概互联网 优雇互联网科技有限公司 蓝思科技飞鸽互联网 互联网科技工作委员会副主任毛军 涨乐互联网科技 长亮科技互联网金融 互联网大会黑科技排名 上海京穆互联网科技有限公司 互联网企业科技类企业如何做账 2021世界互联网领先科技成果发布 上海乐五互联网科技有限公司 江苏互联网智能科技产品出厂价
0