vue-property-decorator
這個組件完全依賴于vue-class-component.它具備以下幾個屬性:
@Component (完全繼承于vue-class-component)
@Emit
@Inject
@Provice
@Prop
@Watch
@Model
Mixins? (在vue-class-component中定義);
使用
當(dāng)我們在vue單文件中使用TypeScript時,引入vue-property-decorator之后,script中的標(biāo)簽就變?yōu)檫@樣:
<script lang="ts">import{Vue,Component}from'vue-property-decorator';@Component({})exportdefaultclass"組件名"extendsVue{ValA:string="hello world";ValB:number=1;}</script>
等同于
<scriptlang="es6">import Vue from 'vue';? ? export default {? ? ? ? data(){? ? ? ? ? ? return {? ? ? ? ? ? ? ? ValA: 'hello world',? ? ? ? ? ? ? ? ValB: 1? ? ? ? ? ? }? ? ? ? }? ? }</script>
總結(jié): 對于data里的變量對頂,我們可以直接按ts定義類變量的寫法寫就可以
那么如果是計算屬性呢? 這就要用到getter了.
<script lang="ts">import{Vue,Component}from'vue-property-decorator';@Component({})exportdefaultclass"組件名"extendsVue{getValA(){return1;}}</script>
等同于
<scriptlang="es6">import Vue from 'vue';? ? export default {? ? ? ? computed: {? ? ? ? ? ? ValA: function() {? ? ? ? ? ? ? ? return 1;? ? ? ? ? ? }? ? ? ? }? ? }</script>
總結(jié): 對于Vue中的計算屬性,我們只需要將該計算屬性名定義為一個函數(shù),并在函數(shù)前加上get關(guān)鍵字即可.
原本Vue中的computed里的每個計算屬性都變成了在前綴添加get的函數(shù).
@Emit
關(guān)于Vue中的事件的監(jiān)聽與觸發(fā),Vue提供了兩個函數(shù)$emit和$on.那么在vue-property-decorator中如何使用呢?
這就需要用到vue-property-decorator提供的@Emit屬性.
<script lang="ts">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');}}</script>
運(yùn)行上面的代碼會打印 'hello' 'world', 為什么呢? 讓我們來看看它等同于什么
<scriptlang="es6">import Vue from 'vue';? ? export default {? ? ? ? mounted(){? ? ? ? ? ? this.$on('emit-todo', function(n) {? ? ? ? ? ? ? ? console.log(n)? ? ? ? ? ? })? ? ? ? ? ? this.emitTodo('world');? ? ? ? },? ? ? ? methods: {? ? ? ? ? ? emitTodo(n){? ? ? ? ? ? ? ? console.log('hello');? ? ? ? ? ? ? ? this.$emit('emit-todo', n);? ? ? ? ? ? }? ? ? ? }? ? }</script>
可以看到,在@Emit裝飾器的函數(shù)會在運(yùn)行之后觸發(fā)等同于其函數(shù)名(駝峰式會轉(zhuǎn)為橫杠式寫法)的事件, 并將其函數(shù)傳遞給$emit.
如果我們想觸發(fā)特定的事件呢,比如在emitTodo下觸發(fā)reset事件:
<script lang="ts">import{Vue,Component,Emit}from'vue-property-decorator';@Component({})exportdefaultclass"組件名"extendsVue{@Emit('reset')emitTodo(n:string){}}</script>
我們只需要給裝飾器@Emit傳遞一個事件名參數(shù)reset,這樣函數(shù)emitTodo運(yùn)行之后就會觸發(fā)reset事件.
總結(jié):在Vue中我們是使用$emit觸發(fā)事件,使用vue-property-decorator時,可以借助@Emit裝飾器來實(shí)現(xiàn).@Emit修飾的函數(shù)所接受的參數(shù)會在運(yùn)行之后觸發(fā)事件的時候傳遞過去.
@Emit觸發(fā)事件有兩種寫法
@Emit()不傳參數(shù),那么它觸發(fā)的事件名就是它所修飾的函數(shù)名.
@Emit(name: string),里面?zhèn)鬟f一個字符串,該字符串為要觸發(fā)的事件名.
@Watch
我們可以利用vue-property-decorator提供的@Watch裝飾器來替換Vue中的watch屬性,以此來監(jiān)聽值的變化.
在Vue中監(jiān)聽器的使用如下:
exportdefault{watch:{'child':this.onChangeValue// 這種寫法默認(rèn) `immediate`和`deep`為`false`,'person':{handler:'onChangeValue',immediate:true,deep:true}},methods:{onChangeValue(newVal,oldVal){// todo...}}}
那么我們?nèi)绾问褂聾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...}
總結(jié):@Watch使用非常簡單,接受第一個參數(shù)為要監(jiān)聽的屬性名 第二個屬性為可選對象.@Watch所裝飾的函數(shù)即監(jiān)聽到屬性變化之后的操作.
@Prop
我們在使用Vue時有時會遇到子組件接收父組件傳遞來的參數(shù).我們需要定義Prop屬性.
比如子組件從父組件接收三個屬性propA,propB,propC.
propA類型為Number
propB默認(rèn)值為default value
propC類型為String或者Boolean
export default{props:{propA:{type:Number},
? ? propB:{default:'default value'},
? ? propC:{type:[String,Boolean]},}}
我們使用vue-property-decorator提供的@Prop可以將上面的代碼改造為如下:
<script lang="ts">import{Vue,Component,Prop}from'vue-property-decorator';@Component({})exportdefaultclass"組件名"extendsVue{@Prop(Number)propA!:number;@Prop({default:'default value'})propB!:string;@propC([String,Boolean])propC:string|boolean;}</script>
這里!和可選參數(shù)?是相反的,!告訴TypeScript我這里一定有值.
總結(jié):@Prop接受一個參數(shù)可以是類型變量或者對象或者數(shù)組.@Prop接受的類型比如Number是JavaScript的類型,之后定義的屬性類型則是TypeScript的類型.
Mixins
在使用Vue進(jìn)行開發(fā)時我們經(jīng)常要用到混合,結(jié)合TypeScript之后我們有兩種mixins的方法.
一種是vue-class-component提供的.
//定義要混合的類 mixins.tsimportVuefrom'vue';importComponentfrom'vue-class-component';@Component// 一定要用Component修飾exportdefaultclassmyMixinsextendsVue{value:string="Hello"}
// 引入importComponent{mixins}from'vue-class-component';importmyMixinsfrom'mixins.ts';@ComponentexportclassmyComponentextendsmixins(myMixins){// 直接extends myMinxins 也可以正常運(yùn)行created(){console.log(this.value)// => Hello}}
第二種方式是在@Component中混入.
我們改造一下mixins.ts,定義vue/type/vue模塊,實(shí)現(xiàn)Vue接口
// mixins.tsimport{Vue,Component}from'vue-property-decorator';declaremodule'vue/types/vue'{interfaceVue{value:string;}}@ComponentexportdefaultclassmyMixinsextendsVue{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}}
總結(jié): 兩種方式不同的是在定義mixins時如果沒有定義vue/type/vue模塊, 那么在混入的時候就要繼承該mixins; 如果定義vue/type/vue模塊,在混入時可以在@Component中mixins直接混入.
@Model
Vue組件提供model:{prop?: string, event?: string}讓我們可以定制prop和event.
默認(rèn)情況下,一個組件上的v-model會把value用作prop且把input用作event,但是一些輸入類型比如單選框和復(fù)選框按鈕可能想使用value prop來達(dá)到不同的目的。使用model選項(xiàng)可以回避這些情況產(chǎn)生的沖突。
下面是Vue官網(wǎng)的例子
Vue.component('my-checkbox',{model:{prop:'checked',event:'change'},props:{// this allows using the `value` prop for a different purposevalue:String,// use `checked` as the prop which take the place of `value`checked:{type:Number,default:0}},// ...})
<my-checkboxv-model="foo"value="some value"></my-checkbox>
上述代碼相當(dāng)于:
<my-checkbox:checked="foo"@change="val => { foo = val }"value="some value"></my-checkbox>
即foo雙向綁定的是組件的checke, 觸發(fā)雙向綁定數(shù)值的事件是change
使用vue-property-decorator提供的@Model改造上面的例子.
import{Vue,Component,Model}from'vue-property-decorator';@ComponentexportclassmyCheckextendsVue{@Model('change',{type:Boolean})checked!:boolean;}
總結(jié),@Model()接收兩個參數(shù), 第一個是event值, 第二個是prop的類型說明, 與@Prop類似, 這里的類型要用JS的. 后面在接著是prop和在TS下的類型說明.
作者:Homary
鏈接:http://www.itdecent.cn/p/d8ed3aa76e9b
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。