一起写一个即插即用的Vue Loading插件实现

2020-06-12 20:52:04易采站长站整理

}
},
data () {
return { isLoading: true }
},
watch: {
source: function () {
if (this.source) {
this.isLoading = false
}
}
}
}
</script>
<style scoped>
....
</style>

不用关心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事件


<template>
...
</template>
<script>
export default {

props: {
source: {
require: true
},
urls: {
type: Array,
default: () => { new Array() }
}
},
data () {
return { isLoading: true }
},
watch: {
source: function () {
if (this.source) {
this.isLoading = false
}
}
},
mounted: function () {
if (this.urls) {
this.__loader_checks.push((url, config) => {
if (this.urls.indexOf(url) !== -1) {