视频教程
1. 什么是装饰器
装饰器是一种特殊类型的声明,可以被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 这样的语法,其中 expression 指向一个生成装饰器函数的表达式。装饰器函数会在运行时被调用,传入被装饰的声明作为参数,并有机会修改或增强其行为
1.1. 新建一个文件夹 descriptor
npm install typescript -g
npm install ts-node-dev -g
tsc --init
1.2. 在这个目录下新建index.ts
const bar = (num: number) => {
console.log(num);
}
bar(10);
tsnd .\index.ts
1.3. 现在我们来体验装饰器
function decotators(target: any) {
console.log('target', target);
}
@decotators
class Xt {
constructor() {
}
}
当我们在运行tsnd .\index.ts时,可以看到此时报错了,原因是装饰器还是实验性特性,要使用需要开启装饰器写法配置
我们需要把experimentalDecorators设置为true
我们再执行tsnd .\index.ts,就正常了
2. 类装饰器 主要是通过 @ 符号添加装饰器
@ 符号用于标记和调用装饰器函数的一种语法糖
他会自动把class的构造函数传入到装饰器的第一个参数 target,然后通过prototype可以自定义添加属性和方法
function decotator(target: any) {
target.prototype.name = 'xt'
}
@decotator
class Xt {
constructor() {
}
}
const xt: any = new Xt()
console.log(xt.name)
3. 属性装饰器
同样使用@符号给属性添加装饰器,他会返回两个参数:
- 1.原形对象
- 2.属性的名称
const decotator: PropertyDecorator = (target: any, key: string | symbol) => {
console.log(target, key)
}
class Xt {
@decotator
public name: string
constructor() {
this.name = ''
}
getName() {
return this.name
}
}
4. 参数装饰器
同样使用@符号给属性添加装饰器,他会返回两个参数:
- 1.原形对象
- 2.方法的名称
- 3.参数的位置从0开始
const decotator: ParameterDecorator = (target: Object, key: string | symbol | undefined, index: number) => {
console.log(target, key, index)
}
class Xt {
public name: string
constructor() {
this.name = ''
}
getName(name:string,@decotator age:number) {
return this.name
}
}
5. 方法装饰器
同样使用@符号给属性添加装饰器,他会返回两个参数:
- 1. 原形对象
- 2. 方法的名称
- 3. 属性描述符 可写对应writable,可枚举对应enumerable,可配置对应configurable
const decotator: MethodDecorator = (target: any, key: string | symbol, descriptor: any) => {
console.log(target, key, descriptor)
}
class Xt {
public name: string
constructor() {
this.name = ''
}
@decotator
getName(name: string, age: number) {
return this.name
}
}
6. 自定义装饰器
const log: MethodDecorator = (target: any, key: string | symbol, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log('先打印');
return originalMethod.apply(this, args);
};
};
class Xt {
@log
myMethod() {
console.log('myMethod');
}
}
const xt = new Xt();
xt.myMethod();
const log = (prefix: string): MethodDecorator => {
return (target, key, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`${prefix}先打印`);
return originalMethod.apply(this, args);
};
};
};
class Xt {
@log('11')
myMethod() {
console.log('2222');
}
}
const xt = new Xt();
xt.myMethod();
import axios from 'axios'
const Get = (url: string): MethodDecorator => {
return (target, key, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
axios.get(url).then(res => {
originalMethod(res, {
status: 200,
})
}).catch(e => {
originalMethod(e, {
status: 500,
})
})
}
}
class Xt {
constructor() {
}
@Get('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
getList (res: any, status: any) {
console.log(res.data.result.list, status)
}
}