Vue3+Typescript封装Pinia插件,优雅管理所有请求的loading效果

为什么要管理项目的loading效果?

  1. 页面数据是通过接口获取的,所有是异步的,那么用户操作下去的时候如果没有loading效果那么页面会显得很呆
  2. 如果一个接口一个loading,那么项目会存在非常多的冗余代码,例如下面这样
.....一些变量....
const loading = ref(false);

const handler = async()=>{
	loading.value = true;
	let res = await fetchXXX();
	loading.value = false;
	....其他业务...
}

从上面可以看出,只要涉及到异步操作,都有可能需要一个loading效果,所以如何优雅处理页面loaidng效果呢?

参考dva-loading到实现原理,通过拦截用户的异步操作,统一管理loading效果,但是dva只有react版本,因为内部是封装了redux和redux-sagas,好在Vue有Pinia这个新的状态管理工具,他是支持自定义插件,并且这个新的状态管理库非常好用good!(具体可以自己去dva查看dva官网)


详细的用法我就不在这里细说了,直接说这个插件如果实现吧,我参考了一个git库,修改了他的一些代码,现在也用在自己的项目中,还不错,这个是作者的git地址git仓库
我改后的代码如下

import type { PiniaPluginContext } from 'pinia'
import { reactive } from 'vue';

export function PiniaLoading({ options, store }: PiniaPluginContext) {
  if (options.actions) {
    const $loading  = reactive<Record<string,boolean>>({});
    Object.keys(options.actions).forEach((actionKey) => {
      const originAction = options.actions[actionKey]
      const action = function(this: unknown, ...args : unknown[]) {
        const rtn = originAction.apply(this, args)
        if (rtn instanceof Promise) {
          $loading[actionKey] = false;
          return new Promise((resolve, reject) => {
						$loading[actionKey] = true;
            rtn
              .then(resolve)
              .catch(reject)
              .finally(() => {
                $loading[actionKey] = false;
              })
          })
        } else {
          return rtn
        }
      }
      store[actionKey] = action
    })
  	store.$loading = $loading
  }
}
declare module 'pinia' {
	// eslint-disable-next-line
	export interface PiniaCustomProperties<Id, S, G, A> {
		$loading: {
			[K in keyof A as A[K] extends (...args: any) => Promise<any> ? K : never]: boolean;
		};
	}
}

然后在页面中就可以直接使用模块名下的对应方法名来当作loading的值了,插件内部会自动处理好loading效果;

例如这个权限模块下有个action方法是用来获取角色群仙列表的

1:对应模块的action中的一个方法

2.在对应的.Vue文件中导入该模块(pinia用法)
在这里插入图片描述
3.直接使用模块名.$loading.模块的action对应的方法名就是loading
Vue3+Typescript封装Pinia插件,优雅管理所有请求的loading效果_第1张图片

到此大功告成、不需要每次都定义loading、然后手动改变loading的值了,有兴趣的小伙伴可以自己导进去玩玩

你可能感兴趣的:(Vue专栏,typescript,javascript,前端,vue3,Pinia)