1.安装npmi-svue-property-decorator2.用法1.@Component(options:ComponentOptions={})@Component装饰器可以接收一个对象作为参数,可以是用于在不提供装饰器选项的对象中声明组件、过滤器、指令等,也可以声明computed、watch等。import{Vue,Component}from'vue-property-decorator'@Component({过滤器:{toFixed:(num:number,fix:number=2)=>{returnnum.toFixed(fix)}}})exportdefaultclassMyComponentextendsVue{publiclist:number[]=[0,1,2,3,4]getevenList(){returnthis.list.filter((item:number)=>item%2===0)}}2,@Prop(options:(PropOptions|Constructor[]|Constructor)={})@Prop装饰器接收一个参数,这个参数可以有三种写法:构造函数,比如String,Number,Boolean等,指定prop的类型;Constructor[],指定prop的可选类型;PropOptions,你可以使用以下选项:type,default,required,validator。import{Vue,Component,Prop}from'vue-property-decorator'@Componentexport默认类MyComponentextendsVue{@Prop(String)publicpropA:string|未定义@Prop([String,Number])publicpropB!:string|number@Prop({type:String,default:'abc'})publicpropC!:string}相当于下面的js写法exportdefault{props:{propA:{type:Number},propB:{default:'defaultvalue'},propC:{type:[String,Boolean]}}}注意:属性的ts类型后面需要跟undefined类型;或者属性名后跟!,表示非null非undefined断言,否则编译器会给出错误信息;指定的默认值必须写在上面的例子中。如果直接在属性名后面赋值,会覆盖该属性并报错。3.@PropSync(propName:string,options:(PropOptions|Constructor[]|Constructor)={})@PropSync装饰器和@prop用法类似,两者的区别是:@PropSync装饰器接收两个参数:propName:string表示父组件传递的属性名;选项:构造函数|构造函数[]|PropOptions与@Prop的第一个参数一致;@PropSync将生成一个新的计算属性。import{Vue,Component,PropSync}from'vue-property-decorator'@ComponentexportdefaultclassMyComponentextendsVue{@PropSync('propA',{type:String,default:'abc'})publicsyncedPropA!:string}等效在下面的js写法中exportdefault{props:{propA:{type:String,default:'abc'}},computed:{syncedPropA:{get(){returnthis.propA},set(value){this.$emit('update:propA',value)}}}}注意:@PropSync需要使用4加上父组件的.sync修饰符,@Model(event?:string,options:(PropOptions|Constructor[]|Constructor)={})@Model装饰器允许我们在组件上自定义v-model,接收两个参数:event:字符串事件名称。选项:构造函数|构造函数[]|PropOptions与@Prop的第一个参数一致。import{Vue,Component,Model}from'vue-property-decorator'@ComponentexportdefaultclassMyInputextendsVue{@Model('change',{type:String,default:'123'})publicvalue!:string}等效在下面的js写法中exportdefault{model:{prop:'value',event:'change'},props:{value:{type:String,default:'123'}}}中指定了change事件上面的例子,所以我们还需要在模板中添加相应的事件:不了解自定义v-model的同学可以查看自定义事件5、@Watch(path:string,options:WatchOptions={})@Watch装饰器接收两个参数:path:string监听的名字财产;options?:WatchOptions={}options可以包含两个属性:immediate?:boolean监听开始后是否立即调用回调函数;deep?:boolean当被监控对象的属性改变时,是否调用回调函数;监听开始,发生在beforeCreate钩子之后,创建的钩子之前,老娃lue:string){}@Watch('arr',{immediate:true,deep:true})publiconArrChanged1(newValue:number[],oldValue:number[]){}@Watch('arr')publiconArrChanged2(newValue:number[],oldValue:number[]){}}相当于下面的js写法exportdefault{watch:{msg:[{handler:'onMsgChanged',immediate:false,deep:false}],arr:[{handler:'onArrChanged1',immediate:true,deep:true},{handler:'onArrChanged2',immediate:false,deep:false}]},方法:{onMsgVhanged(newValue,oldValue){},onArrChange1(newValue,oldValue){},onArrChange2(newValue,oldValue){}}}6、@Emit(event?:string)@Emit装饰器接收一个可选参数,它是$Emit的第一个参数,作为事件名if如果不提供该参数,$Emit会将回调函数名的camelCase转换为kebab-case作为事件名;@Emit会把回调函数的返回值作为第二个参数,如果返回值是一个Promise对象,$emit会在Promise对象被标记为resolved后触发;@Emit的回调函数的参数会放在它的返回值之后,和$emit一起作为参数使用。import{Vue,Component,Emit}from'vue-property-decorator'@ComponentexportdefaultclassMyComponentextendsVue{count=0@Emit()publicaddToCount(n:number){this.count+=n}@Emit('重置')publicresetCount(){this.count=0}@Emit()publicreturnValue(){return10}@Emit()publiconInputChange(e){returne.target.value}@Emit()publicpromise(){returnnewPromise(resolve=>{setTimeout(()=>{resolve(20)},0)})}}等同于下面的js写法exportdefault{data(){return{count:0}},方法:{addToCount(n){this.count+=nthis.$emit('add-to-count',n)},resetCount(){this.count=0this.$emit('reset')},returnValue(){this.$emit('return-value',10)},onInputChange(e){this.$emit('on-input-change',e.target.value,e)},promise(){constpromise=newPromise(resolve=>{setTimeout(()=>{resolve(20)},0)})promise.then(value=>{this.$emit('promise',value)})}}}7、@Ref(refKey?:string)@Ref装饰接收者接收一个可选参数,用于指向元素或子组件的引用信息如果不提供该参数,装饰器后面的属性名将作为参数extendsVue{@Ref()readonlyloginForm!:Form@Ref('changePasswordForm')readonlypasswordForm!:FormpublichandleLogin(){this.loginForm.validate(valide=>{if(valide){//登录...}else{//错误提示}})}}相当于下面的js写法:false,get(){returnthis.$refs.changePasswordForm}}}}@Provide/@Inject和@ProvideReactive/@InhectReactive平时不使用provide/inject选项,暂时搁置being,以后有空再研究。参考:https://github.com/kaorun343/...