Typescript —— 装饰器在实际项目中的应用

273 阅读2分钟

一、什么是Typescript装饰器

1.1、概念以及用法

关于装饰器,请参考我的另一篇文章装饰器

二、Typescript环境的搭建

关于Typescript环境的搭建,请参考我的另一篇文章搭建一个ts环境

二、装饰器在实际项目中的应用

2.1一个简单的koa例子

import * as Koa from "koa";
import * as KoaRouter from "koa-router";
const app = new Koa();
const router = new KoaRouter();

router.get("/user", (ctx) => {
    ctx.body = "/user";
})

router.get("/order", (ctx) => {
    ctx.body = "/order";
})
// 调用加载器
app.use(router.routes());
app.listen(4001, () => {
    console.log("服务器启动成功");
})

上面是一个很简单的koa的例子,定义了俩个接口/user/order,但是在我们实际项目中,有各种模块,这样定义路由,会让代码维护越来越困难。也许有人会说,那我可以分文件呀,一个模块一个文件,这样做不是不可以,但不是最优的选择,程序就是设计,我们要写出逼格高的代码。

2.2开始

看一下总的目录结构

image.png

2.2.1定义装饰器(核心)

utils/routerDector.ts

import * as Router from "koa-router";
import { glob } from "glob";
const router = new Router();

//定义装饰器工厂的工厂
const creatDes: Function = (router: Router) => (method: string) => (url: string) => {
    return function (target, property, descriptor: PropertyDescriptor) {
        router[method](url, descriptor.value);

    }
}
const createMethod = creatDes(router);
export const get = createMethod("get");
export const post = createMethod("post");

2.2.2定义路由

order.ts

import { get, post } from "../utils/routerDector";
class Order {
    @get("/list")
    list(ctx) {
        ctx.body = "订单列表"
    }


}

user.ts

import { get, post } from "../utils/routerDector";
class User {
    @post("/add")
    add(ctx) {
        ctx.body = "/add";
    }

    @get("/print")
    print(ctx) {
        ctx.body = "/print"
    }
}

2.2.3定义加载器

修改utils/routerDector.ts文件

import * as Router from "koa-router";
import { glob } from "glob";
const router = new Router();

const creatDes: Function = (router: Router) => (method: string) => (url: string) => {
    return function (target, property, descriptor: PropertyDescriptor) {
        router[method](url, descriptor.value);

    }
}
const createMethod = creatDes(router);
export const get = createMethod("get");
export const post = createMethod("post");

// 加载器
export const load = (folder: string) => {
    const extname = ".{js,ts}";
    glob.sync(require("path").join(folder, `./**/*${extname}`)).forEach(item => {
        require(item);
    });
    return router;
}

2.2.4调用加载器,加载路由

index.ts文件中

import * as Koa from "koa";
import { load } from "./utils/routerDector"
import { resolve } from "path";
const app = new Koa();

// 调用加载器
const router = load(resolve(__dirname, "./router"));
app.use(router.routes());
app.listen(4001, () => {
    console.log("服务器启动成功");
})