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(),
};
}
如何引入及使用?
- 在需要收集的api上使用装饰器进行修饰。
例:
export default class testModel {
@GET
testApi(params: any) {
return axios.get<any>({
url: `/test`,
params,
});
}
}
- 在index.ts中引入所有使用了装饰器的模块,确保所有的装饰器被成功编译。
const models = import.meta.globEager('./model/*.ts'); //这里是使用vite的import方式.
- 在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装饰器的实现到此为止,欢迎大家讨论和提出问题。