注意:在ts中使用装饰器,tsconfig中要设置"experimentalDecorators": true!!!
在ts中,有四种装饰器需要我们学习。四种装饰器不同之处在于装饰的对象不同,分别有装饰类的,装饰类中的属性的,装饰类中的函数的,装饰类中函数的参数的。装饰器是一个函数,可以为装饰的对象添加新内容,最基础的写法为:
function 装饰器名(args){
...
}
@装饰器名 装饰对象
1.给类加装饰器
给类Comp加上装饰器classdecorator:
function classdecorator(target:any){
target.prototype.lala = 'a'
}
@classdecorator
class Comp{}
let com = new Comp()
console.log(com.lala) //a
但是上例在ts中会报错,因为在类Comp中没有该类型的定义。还有另一种写法不会报错:
function classdecorator(target:any){
return class extends target{
lala = 'a'
}
}
@classdecorator
class Comp{}
let com = new Comp()
小插曲——简单模拟React中的connect装饰器😄:
function connect(mapState:any,mapDispatch:any){
return function(target:any){
target.prototype.props = {
mapState,
mapDispatch
}
}
}
@connect(
()=>{
console.log('mapstate')
},
()=>{
console.log('mapDispatch')
}
)
class React{
props:any
}
let com = new React()
com.props.mapState()
com.props.mapDispatch()
2.给类的属性加装饰器
function prode(target,name){ //被装饰的类 被装饰的属性名
console.log(target,name) //Comp {} props
target[name] = 'lzx'
target['from'] = 'hainan' //在装饰器中定义新的属性
}
class Comp{
@prode
name:string = 'zzm'
}
let com = new Comp()
console.log(com.name) //zzm *在类中对该属性赋值优先级高于在装饰器中对该属性赋值
console.log(com.from) //hainan 但是会报错,原因和第一个例子一样
3.给类的方法加装饰器
function funde(param:string){
console.log(param)
//类 方法名 方法的描述符
return function(target:any,key:string,description:{[propsname:string]:any}){
console.log(target,key,description)
}
}
class Comp{
name:string = 'zzm'
@funde('ooo')
say(){}
}
4.给类的方法的参数加装饰器
function funde(param:string){
console.log(param)
return function(target:any,key,index){ //类 方法名 参数下标
console.log(target,key,index) //Comp {} say 1 (换行)Comp {} say 0
target[key][0] = '我' //该处的赋值改变不了函数里的结果
}
}
class Comp{
name:string = 'zzm'
//装饰器从后往前执行
say(@funde('lalala') word1:string,@funde('yeyeye') word2:string){}
}
let com = new Comp()
com.say('你','最胖了')
四种装饰器的优先级
function clsde(target:any){
console.log('类')
}
function prop(target,name){
console.log('类属性')
}
function func(target,key,description){
console.log('类方法')
}
function funcProp(parm){
return function(target,key,index){
console.log('类方法参数'+parm)
}
}
@clsde
class House{
@prop
name:string
@func
say(@funcProp('0') param1,@funcProp('1') param2){}
}
输出结果:
类属性
类方法参数1
类方法参数0
类方法
类
关系tips:
- 类的优先级最低
- 类方法参数从右到左优先级依次降低,类方法参数优先于类方法
- 类方法和类属性优先级同级,谁在上面谁先执行