Pinia+ts实现api装饰器

264 阅读2分钟

api装饰器是什么?

在node.js写服务端的过程中,我见过路由装饰器这种写法,即用装饰器快速收集到所有的路由,然后一并注册,所以我就想前端可不可以也通过装饰器来集中收集api并进行调用呢?那就是本文的内容,api装饰器

api装饰器能干什么,有何优势?

在api装饰器中,我将api装饰器的类型按请求方法划分为四种,GET,POST,PUT,DELETE,这四种类型分别对应着四种请求方法的api,比如GET装饰器中收集的全是get类型的请求。api装饰器实现了四种类型的api的收集,并对请求进行了分类,而且可以集中进行引入并调用。

import { listApi } from './listModel' 
import { getInfoApi } from './infoModel';
import { menuApi } from './menuModel';
import { roleApi } from './roleModel'; //以往的api引入方式;

------------------------------------------------

import { useApi } from './useApi';

const { GetAll } = useApi();
const { listApi, getInfoApi, menuApi, roleApi } = GetAll; //使用api装饰器的引入方式


优势见上述代码,当一个页面需要从多个不同的文件引入多个api时,api装饰器的写法能够极大的简化api的引入,且不需要慢慢去寻找api所在文件的路径,直接引入。

如何实现?

简单的原理是:通过装饰器得到api的具体信息之后,将api存入pinia之中,实现api的保存,以及通过pinia可以在多页面进行获取。

import { useApiStore } from './store/modules/api';
const apiStore = useApiStore();
const { setGet, setPost, setPut, setDelete } = apiStore;
export function useApi() {
  function GET(target, property, descriptor) {
    setGet(property, descriptor.value); //descriptor.value即是收集到的api,通过Pinia存入store里
  }
  function POST(target, property, descriptor) {
    setPost(property, descriptor.value);
  }
  function PUT(target, property, descriptor) {
    setPut(property, descriptor.value);
  }
  function DELETE(target, property, descriptor) {
    setDelete(property, descriptor.value);
  }
  function GetAll() {
    return apiStore.Get;
  }
  function PostAll() {
    return apiStore.Post;
  }
  function PutAll() {
    return apiStore.Put;
  }
  function DeleteAll() {
    return apiStore.Delete;
  }
  return {
    GET,
    POST,
    PUT,
    DELETE,
    GetAll: GetAll(),
    PostAll: PostAll(),
    PutAll: PutAll(),
    DeleteAll: DeleteAll(),
  };
}

如何引入及使用?

  1. 在需要收集的api上使用装饰器进行修饰。

例:

export default class testModel {
  @GET
  testApi(params: any) {
    return axios.get<any>({
      url: `/test`,
      params,
    });
  }
 }
  1. 在index.ts中引入所有使用了装饰器的模块,确保所有的装饰器被成功编译。
const models = import.meta.globEager('./model/*.ts'); //这里是使用vite的import方式.
  1. 在main.ts中引入收集了所有api的index.ts。
async function init(){
...省略
await import('./api/index'); //这里需要动态引入,静态引入的话pinia会报错,因为装饰器是在编译时触发的,而pinia在编译时还没有装载。
...省略
}

4.页面中使用

import { useApi } from './useApi';
//... 省略生命周期
const { GetAll } = useApi();
const { listApi, getInfoApi, menuApi, roleApi } = GetAll; 

api装饰器的实现到此为止,欢迎大家讨论和提出问题。