vue-property-decorator用法详解
vue-property-decorator
这个组件完全依赖于vue-class-component.它具备以下几个属性:
- @Component(完全继承于vue-class-component)
- @Emit
- @Inject
- @Provice
- @Prop
- @Watch
- @Model
- Mixins(在vue-class-component中定义);
使用
当我们在vue单文件中使用TypeScript时,引入vue-property-decorator之后,script中的标签就变为这样:
import{Vue,Component}from'vue-property-decorator'; @Component({}) exportdefaultclass"组件名"extendsVue{ ValA:string="helloworld"; ValB:number=1; }
等同于
importVuefrom'vue'; exportdefault{ data(){ return{ ValA:'helloworld', ValB:1 } } }
总结:对于data里的变量对顶,我们可以直接按ts定义类变量的写法写就可以
那么如果是计算属性呢?这就要用到getter了.
import{Vue,Component}from'vue-property-decorator'; @Component({}) exportdefaultclass"组件名"extendsVue{ getValA(){ return1; } }
等同于
importVuefrom'vue'; exportdefault{ computed:{ ValA:function(){ return1; } } }
总结:对于Vue中的计算属性,我们只需要将该计算属性名定义为一个函数,并在函数前加上get关键字即可.
原本Vue中的computed里的每个计算属性都变成了在前缀添加get的函数.
@Emit
关于Vue中的事件的监听与触发,Vue提供了两个函数$emit和$on.那么在vue-property-decorator中如何使用呢?
这就需要用到vue-property-decorator提供的@Emit属性.
import{Vue,Component,Emit}from'vue-property-decorator'; @Component({}) exportdefaultclass"组件名"extendsVue{ mounted(){ this.$on('emit-todo',function(n){ console.log(n) }) this.emitTodo('world'); } @Emit() emitTodo(n:string){ console.log('hello'); } }
运行上面的代码会打印'hello''world',为什么呢?让我们来看看它等同于什么
importVuefrom'vue'; exportdefault{ mounted(){ this.$on('emit-todo',function(n){ console.log(n) }) this.emitTodo('world'); }, methods:{ emitTodo(n){ console.log('hello'); this.$emit('emit-todo',n); } } }
可以看到,在@Emit装饰器的函数会在运行之后触发等同于其函数名(驼峰式会转为横杠式写法)的事件,并将其函数传递给$emit.
如果我们想触发特定的事件呢,比如在emitTodo下触发reset事件:
import{Vue,Component,Emit}from'vue-property-decorator'; @Component({}) exportdefaultclass"组件名"extendsVue{ @Emit('reset') emitTodo(n:string){ } }
我们只需要给装饰器@Emit传递一个事件名参数reset,这样函数emitTodo运行之后就会触发reset事件.
总结:在Vue中我们是使用$emit触发事件,使用vue-property-decorator时,可以借助@Emit装饰器来实现.@Emit修饰的函数所接受的参数会在运行之后触发事件的时候传递过去.
@Emit触发事件有两种写法
- @Emit()不传参数,那么它触发的事件名就是它所修饰的函数名.
- @Emit(name:string),里面传递一个字符串,该字符串为要触发的事件名.
@Watch
我们可以利用vue-property-decorator提供的@Watch装饰器来替换Vue中的watch属性,以此来监听值的变化.
在Vue中监听器的使用如下:
exportdefault{ watch:{ 'child':this.onChangeValue //这种写法默认`immediate`和`deep`为`false` , 'person':{ handler:'onChangeValue', immediate:true, deep:true } }, methods:{ onChangeValue(newVal,oldVal){ //todo... } } }
那么我们如何使用@Watch装饰器来改造它呢?
import{Vue,Component,Watch}from'vue-property-decorator'; @Watch('child') onChangeValue(newVal:string,oldVal:string){ //todo... } @Watch('person',{immediate:true,deep:true}) onChangeValue(newVal:Person,oldVal:Person){ //todo... }
总结: @Watch使用非常简单,接受第一个参数为要监听的属性名第二个属性为可选对象.@Watch所装饰的函数即监听到属性变化之后的操作.
@Prop
我们在使用Vue时有时会遇到子组件接收父组件传递来的参数.我们需要定义Prop属性.
比如子组件从父组件接收三个属性propA,propB,propC.
- propA类型为Number
- propB默认值为defaultvalue
- propC类型为String或者Boolean
exportdefault{ props:{ propA:{ type:Number }, propB:{ default:'defaultvalue' }, propC:{ type:[String,Boolean] }, } }
我们使用vue-property-decorator提供的@Prop可以将上面的代码改造为如下:
import{Vue,Component,Prop}from'vue-property-decorator'; @Component({}) exportdefaultclass"组件名"extendsVue{ @Prop(Number)propA!:number; @Prop({default:'defaultvalue'})propB!:string; @propC([String,Boolean])propC:string|boolean; }
这里!和可选参数?是相反的,!告诉TypeScript我这里一定有值.
总结:@Prop接受一个参数可以是类型变量或者对象或者数组.@Prop接受的类型比如Number是JavaScript的类型,之后定义的属性类型则是TypeScript的类型.
Mixins
在使用Vue进行开发时我们经常要用到混合,结合TypeScript之后我们有两种mixins的方法.
一种是vue-class-component提供的.
//定义要混合的类mixins.ts importVuefrom'vue'; importComponentfrom'vue-class-component'; @Component//一定要用Component修饰 exportdefaultclassmyMixinsextendsVue{ value:string="Hello" }
//引入 importComponent{mixins}from'vue-class-component'; importmyMixinsfrom'mixins.ts'; @Component exportclassmyComponentextendsmixins(myMixins){ //直接extendsmyMinxins也可以正常运行 created(){ console.log(this.value)//=>Hello } }
第二种方式是在@Component中混入.
我们改造一下mixins.ts,定义vue/type/vue模块,实现Vue接口
//mixins.ts import{Vue,Component}from'vue-property-decorator'; declaremodule'vue/types/vue'{ interfaceVue{ value:string; } } @Component exportdefaultclassmyMixinsextendsVue{ value:string='Hello' }
混入
import{Vue,Component,Prop}from'vue-property-decorator'; importmyMixinsfrom'@static/js/mixins'; @Component({ mixins:[myMixins] }) exportdefaultclassmyComponentextendsVue{ created(){ console.log(this.value)//=>Hello } }
总结:两种方式不同的是在定义mixins时如果没有定义vue/type/vue模块,那么在混入的时候就要继承该mixins;如果定义vue/type/vue模块,在混入时可以在@Component中mixins直接混入.
@Model
Vue组件提供model:{prop?:string,event?:string}让我们可以定制prop和event.
默认情况下,一个组件上的v-model会把value用作prop且把input用作event,但是一些输入类型比如单选框和复选框按钮可能想使用valueprop来达到不同的目的。使用model选项可以回避这些情况产生的冲突。
下面是Vue官网的例子
Vue.component('my-checkbox',{ model:{ prop:'checked', event:'change' }, props:{ //thisallowsusingthe`value`propforadifferentpurpose value:String, //use`checked`asthepropwhichtaketheplaceof`value` checked:{ type:Number, default:0 } }, //... })
上述代码相当于:
{foo=val}" value="somevalue">
即foo双向绑定的是组件的checke,触发双向绑定数值的事件是change
使用vue-property-decorator提供的@Model改造上面的例子.
import{Vue,Component,Model}from'vue-property-decorator'; @Component exportclassmyCheckextendsVue{ @Model('change',{type:Boolean})checked!:boolean; }
总结,@Model()接收两个参数,第一个是event值,第二个是prop的类型说明,与@Prop类似,这里的类型要用JS的.后面在接着是prop和在TS下的类型说明.
暂时常用的就这几个,还有@Provice和@Inject等用到了再写.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。