VuePropertyDecoratorInstall需要用到vue-property-decorator这个库npmi-Svue-property-decoratorUsage有几个修改器和1个function(Mixin):@Prop@PropSync@Model@Watch@Provide@Inject@ProvideReactive@InjectReactive@Emit@Ref@Component(vue-class-component提供)Mixins(vue-class-component提供的名为mixins的辅助函数)另见vuex-class@Prop(options:(PropOptions|Constructor[]|Constructor)={})decoratorimport{Vue,Component,Prop}from'vue-property-decorator'@Componentexport默认类YourComponentextendsVue{@Prop(Number)readonlypropA:number|undefined@Prop({default:'defaultvalue'})只读propB!:string@Prop([String,Boolean])readonlypropC:string|布尔|undefined}等同于exportdefault{props:{propA:{type:Number},propB:{default:'defaultvalue'},propC:{type:[String,Boolean]}}}提示:如果你想从类型定义中设置每个prop值的类型属性,哟你可以使用reflect-metadata.SetemitDecoratorMetadatatotrue.Importreflect-metadatabeforeimportingvue-property-decorator(importingreflect-metadataisneededonce.)import'reflect-metadata'import{Vue,Component,Prop}from'vue-property-decorator'@ComponentexportdefaultclassMyComponentextendsVue{@Prop()age!:number}每个prop的默认值需要像上面的示例代码一样定义。不支持定义每个默认属性,如@Prop()prop='默认值'。@PropSync(propName:string,options:(PropOptions|Constructor[]|Constructor)={})decoratorimport{Vue,Component,PropSync}from'vue-property-decorator'@Componentexport默认类YourComponentextendsVue{@PropSync('name',{type:String})syncedName!:string}等同于exportdefault{props:{name:{type:String}},computed:{syncedName:{get(){returnthis.name},set(value){this.$emit('update:name',value)}}}}除此之外,它的工作方式与@Prop类似,只是它将propName作为装饰器的参数,此外它还会在后面创建一个计算得到的getter和setter场景。通过这种方式,您可以像常规数据属性一样与该属性进行交互,同时使其像在父组件中附加.sync修饰符一样简单。@Model(event?:string,options:(PropOptions|Constructor[]|Constructor)={})decoratorimport{Vue,Component,Model}from'vue-property-decorator'@ComponentexportdefaultclassYourComponentextendsVue{@Model('change',{type:Boolean})readonlychecked!:boolean}等同于exportdefault{model:{prop:'checked',event:'change'},props:{checked:{type:Boolean}}}@模型属性还可以通过reflect-metadata从其类型定义中设置类型属性。@Watch(path:string,options:WatchOptions={})decoratorimport{Vue,Component,Watch}from'vue-property-decorator'@ComponentexportdefaultclassYourComponentextendsVue{@Watch('child')onChildChanged(val:string,oldVal:string){}@Watch('person',{immediate:true,deep:true})onPersonChanged1(val:Person,oldVal:Person){}@Watch('person')onPersonChanged2(val:Person,oldVal:Person){}}等同于exportdefault{watch:{child:[{handler:'onChildChanged',immediate:false,deep:false}],person:[{handler:'onPersonChanged1',immediate:true,deep:true},{handler:'onPersonChanged2',immediate:false,deep:false}}]},方法:{onChildChanged(val,oldVal){},onPersonChanged1(val,oldVal){},onPersonChanged2(val,oldVal){}}}@Provide(key?:string|symbol)/@Inject(options?:{from?:InjectKey,default?:any}|InjectKey)decoratorimport{Component,Inject,Provide,Vue}from'vue-property-decorator'constsymbol=Symbol('baz')@ComponentexportclassMyComponentextendsVue{@Inject()readonlyfoo!:string@Inject('bar')readonlybar!:string@Inject({from:'optional',default:'default'})readonlyoptional!:string@Inject(symbol)readonlybaz!:string@Provide()foo='foo'@Provide('bar')baz='bar'}等同在constsymbol=Symbol('baz')exportconstMyComponent=Vue.extend({inject:{foo:'foo',bar:'bar',optional:{from:'optional',default:'default'},[symbol]:symbol},data(){return{foo:'foo',baz:'bar'}},provide(){return{foo:this.foo,bar:this.baz}}})@ProvideReactive复制代码(key?:string|symbol)/@InjectReactive(options?:{from?:InjectKey,default?:any}|InjectKey)装饰器这些装饰器是@Provide和@Inject的反应式版本。如果提供的值被父组件修改,那么子组件可以捕获这个modification.constkey=Symbol()@ComponentclassParentComponentextendsVue{@ProvideReactive()one='value'@ProvideReactive(key)two='value'}@ComponentclassChildComponentextendsVue{@InjectReactive()one!:string@InjectReactive(key)two!:string}@Emit(event?:string)decorator@Emit$emit修饰的函数在返回值后跟原始参数。如果返回值是一个promise,它会在发出之前被解析。如果事件的名称没有通过事件参数提供,则使用函数名称。在这种情况下,camelCase名称将被转换为kebab-case.import{Vue,Component,Emit}from'vue-property-decorator'@ComponentexportdefaultclassYourComponentextendsVue{count=0@Emit()addToCount(n:number){this.count+=n}@Emit('reset')resetCount(){this.count=0}@Emit()returnValue(){return10}@Emit()onInputChange(e){returne.目标价值}@Emit()promise(){returnnewPromise(resolve=>{setTimeout(()=>{resolve(20)},0)})}}等同于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)})}}}@Ref(refKey?:string)decoratorimport{Vue,Component,Ref}from'vue-property-decorator'importAnotherComponentfrom'@/path/to/another-component.vue'@Componentexport默认类YourComponentextendsVue{@Ref()readonlyanotherComponent!:AnotherComponent@Ref('aButton')readonlybutton!:HTMLButtonElement}等价于exportdefault{computed(){anotherComponent:{cache:false,get(){returnthis.$refs.anotherComponentasAnotherComponent}},button:{cache:false,get(){returnthis.$refs.aButtonasHTMLButtonElement}}}}关注我公众号不定期分享前端知识,与你共同进步!
