# 1、@Emit的实现原理
@Emit
装饰器是一个函数装饰器。
函数装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
(target: any, propertyKey: string, descriptor: PropertyDescriptor)
1
target
——对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。propertyKey
——成员的名字(被修饰的方法的名字)。descriptor
——成员的属性描述符。
@Emit
装饰器的实现代码如下,主要分为以下几步:
- 将事件名有小驼峰改为由
-
拼接。 - 重写 由
@Emit
装饰器装饰的方法。 - 在重写方法中调用
this.$emit()
,同时将被装饰的函数的返回值作为参数传给this.$emit()
。
export function emit(event: string){
return function(target: Vue,propertyName: string,descriptor: PropertyDescriptor){
//将changeName改为change-name
const eventName=propertyName.replace(/\B([A-Z])/g, '-$1').toLowerCase();
//触发的函数
const originalFn=descriptor.value;
//重写触发函数
descriptor.value=function(this: Vue,...args: any[]){
const emitFn=(returnValue: any)=>{
//防止没有在@emit()中传递事件名称
const emitName=event||eventName;
returnValue?this.$emit.apply(this,[emitName,returnValue,...args]): this.$emit.apply(this,[emitName,...args])
}
//获取添加了@emit装饰器的返回值
const returnValue=originalFn.apply(this,args)
//触发this.$emit()
emitFn(returnValue)
// return returnValue;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2、@Emit在Vue中的使用
import { Component, Prop, Vue} from 'vue-property-decorator';
import {emit} from "@/decorators/emit"
@Component
export default class HelloWorld extends Vue {
@Prop() private msg!: string;
name='test';
@emit('change')
changeName(){
this.name='james';
return this.name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13