效果 每个请求都有自己独立loading 并统一在vuex内
1 request文件夹内放了所有的请求模块,将除了index和serveProxy文件内的请求全部拿出来,给他们做拦截,并且在vuex内配置loading状态
request /index 引入该文件,相当于引入当前目录一下所有请求api
// 集成所有请求
import serviceProxy from './serveProxy.js'
// 一次引入所有函数
const requireAll = requireContext => requireContext.keys().map(requireContext)
/**
* require.context(directory,useSubdirectories,regExp)
* require.context():需要一次性的引入某个文件夹下的所有文件
形参:
directory:需要引入文件的目录 ./当前目录下面所有目录
useSubdirectories:是否查找该目录下的子级目录 true
regExp:匹配引入文件的正则表达式
*/
const res = require.context('./', true, /^(?!\.\/(index|serviceProxy)).*\.js$/)
const checkUnique = (target, obj) => {
Object.keys(obj).forEach(key => {
if (key in target) {
console.error(`存在重复键值 ${key}`)
}
})
} //检查要代理的请求是否重名,重名警告,需要重写配置名称
// requireAll(res) 读取目录下的文件内暴露的模块
// 0: Module
// saveInro: ƒ saveInro(data)
// Symbol(Symbol.toStringTag): "Module"
const service = requireAll(res).reduce((_service, module) => {
//_service //上一次调用回调返回的值,或者是提供的初始值(initialValue)
//module 当前正在被处理的值
checkUnique(_service, module) //将上次的对象和当前正在处理的模块名称进行对比,是否重名
return Object.assign(_service, module) //合并上次和本次的路径数据
}, {}) //初始数据为空对象
// service {'请求名':请求函数体,......} 处理的数据大致状态
// reduce 方法
// function(total,currentValue, index,arr) 第一个参数 函数
// total 初始值, 或者计算结束后的返回值 计算后的值 必须
// currentValue 当前元素 当前正在操作的值 必须
// currentIndex 当前索引 当前正在处理的值 可选
// arr 当前被操作元素所处的arr对象
// initialValue 第二个参数 传递给函数的初始值 可以是[]或者 {} //数据将遍历成数组或对象内
console.log(service)
export const getAjaxProps = () => Object.keys(service) //获取所有请求的键名称
export default serviceProxy(service, getAjaxProps()) //代理
request/serveProxy
// 请求拦截,将所有的请求统一集成在一起,并配置所有请求的状态
/**
* serveAllObject 所有的请求对象 {string:()=>{},...}
* serverAllKey 所有请求对象的键名 Array<string>
*/
import {store} from '@/store/index.js'
const serviceProxy = (serveAllObject, serverAllKey) => {
return new Proxy(serveAllObject, {
get(target, key) {
//target当前正在被获取的对象 key 当前正在被获取对象的键
if (!serverAllKey.includes(String(key))) return target[key] //检查是否存在键,不存在直接返回函数体
const proxy = (...args) => {
return new Promise(async (resolve, reject) => {
store.commit('setloading', {
//处理
key, //要设置请求健名的状态
status: true,
})
let result //请求结果
let hasError = false //是否错误
try {
result = await target[key](...args)
} catch (err) {
result = err
hasError = true
}
store.commit('setloading', {
key,
status: false,
})
hasError ? reject(result) : resolve(result)
})
}
return proxy
},
})
}
export default serviceProxy
tool/tool
//初始化loading状态
export const initAllloadState = (app, store) => {
const loading = getAjaxProps().reduce((res, key) => {
res[key] = false
return res
}, {})
// 初始化 loading 的状态
console.log(isProxy(store.state.loading))
store.commit('initloading', loading)
app.provide(
'$loading',
computed(() => store.state.loading)
)
}
main
import { store } from './store'
import { initAllloadState } from '@/tool/tool.js'
import { svginstall } from '@/icons/index.js'
svginstall(app) //全局安装svg组件
initAllloadState(app,store) //初始化loading状态
vuex
import { createStore } from 'vuex'
export const store = createStore({
state() {
return {
count: 1,
loading: {}, //所有需要拦截请求状态数据,键lbooler
}
},
mutations: {
//单独设置某个loading状态
setloading(state, { key, status = false } = {}) {
state.loading[key] = status
},
//初始化所有loading状态
initloading(state, loading) {
state.loading = loading
},
},
})
使用 可element-ui button
template
<Button :loading="loading.test" @click.stop="handel"></Button>
js
import Button from '@/components/Button'
import Mobile from '@/components/Mobile'
import api from '@/request/index.js'
import { onMounted, inject } from 'vue'
import { usePie } from '@/tool/pie'
export default {
components: {
Button,
Mobile,
},
setup(props) {
const loading = inject('$loading') //获取所有loading的状态
const handel = async () => {
await api.test()
}
usePie('pie')
return {
handel,
loading,
}
},
}
</script>
自己做button
<template>
<div class="BTN" :style="{pointerEvents:loading?'none':'auto'}">
<svg-icon iconClass="loading" :svgClass="svgClass" v-show="loading" :rotate='loading'></svg-icon>
<span v-text='text'></span>
</div>
</template>
<script>
import { computed } from 'vue'
export default {
props: {
loading: {
type: Boolean,
default: false,
},
text:{
type:String,
default:'More Details'
}
},
setup(props) {
const text=computed(()=>props.loading?'正在请求':props.text)
return{
text
}
},
}
</script>
感谢之前小伙伴留下来,今天研究了一了下,用vue3自己试了一下,很好