自定义装饰器
自定义装饰器本质就是个函数
注意
对已知得装饰器调用进行二次封装
对多个装饰器合并
参数装饰器
(一) 对已知得装饰器二次封装
新建一个aaa.decorator.ts
文件
ts
import { SetMetadata } from "@nestjs/common";
export const Aaa = (...args: string[]) => SetMetadata("aaa", args);
我在这里面调用了 SetMetadata 相当于设置权限
新建一个守卫aaa.guard.ts
文件
ts
import {
CanActivate,
ExecutionContext,
Inject,
Injectable,
} from "@nestjs/common";
import { Observable } from "rxjs";
import { Reflector } from "@nestjs/core";
@Injectable()
export class AaaGuard implements CanActivate {
// 注入
@Inject(Reflector)
reflector: Reflector;
canActivate(
context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> {
// 函数里面注入以后 获取值
console.log(this.reflector.get("aaa", context.getHandler()));
// 类里面获取值
console.log(this.reflector.get("aaa", context.getClass()));
// 这里返回 true
return true;
}
}
守卫里面获取到我设置得权限是 aaa 的值.这里注意守卫里面的aaa
与 SetMetadata 里面的aaa
一致
在控制器里面使用
ts
@Get()
@Aaa('admin')
// 替换 @SetMetadata('aaa', 'admin')
@UseGuards(AaaGuard)
findAll() {
return this.aaaService.findAll();
}
这样就能打印出['admin']
(二) 对多个装饰器合并
有的时候装饰器太多了.我们需要合并一个装饰器这里就需要用到 applyDecorators
新建一个bbb.decorator.ts
文件
ts
import { applyDecorators, UseGuards, Get } from "@nestjs/common";
import { Aaa } from "./aaa.decorator";
import { AaaGuard } from "./aaa.guard";
// 这里开始合并
export function BBB(path, role) {
return applyDecorators(Get(path), Aaa(role), UseGuards(AaaGuard));
}
在控制器里面使用
ts
@BBB('', 'admin2')
findAll() {
return this.aaaService.findAll();
}
在访问的时候就是打印出['admin2']
(三) 参数装饰器
我们可以封装一个参数装饰器.在控制器里面使用获取到 header,query,ip 等等
获取到指定的头部信息
- (1) 新建一个文件
ccc.decorator.ts
ts
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
export const CCC = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return data ? request.headers[data.toLowerCase()] : request.headers;
}
);
- (2) 在控制器里面使用
ts
@Get()
findAll(@CCC('Accept') headerAccept) {
console.log(headerAccept);
return this.aaaService.findAll();
}
这样就会打印出头部
获取参数
- (1) 新建一个文件
ddd.decorator.ts
ts
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
export const MyQuery = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.query[data];
}
);
- (2) 在控制器里面使用
ts
@Get()
findAll(@MyQuery('id') query) {
console.log('接受得参数' + query);
return this.aaaService.findAll();
}
注意
参数装饰器同样可以使用管道来验证
比如
@MyQuery('id',new ParseIntPipe()) query
这样就可以验证参数是否为数字