npm i -s vue-property-decorator
1,@Component(options:ComponentOptions = {})html
@Component
裝飾器能夠接收一個對象做爲參數,能夠在對象中聲明 components ,filters,directives
等未提供裝飾器的選項,也能夠聲明computed,watch
等vue
import { Vue, Component } from 'vue-property-decorator' @Component({ filters: { toFixed: (num: number, fix: number = 2) => { return num.toFixed(fix) } } }) export default class MyComponent extends Vue { public list: number[] = [0, 1, 2, 3, 4] get evenList() { return this.list.filter((item: number) => item % 2 === 0) } }
2,@Prop(options: (PropOptions | Constructor[] | Constructor) = {})git
@Prop
裝飾器接收一個參數,這個參數能夠有三種寫法:github
Constructor
,例如String,Number,Boolean
等,指定 prop
的類型;Constructor[]
,指定 prop
的可選類型;PropOptions
,可使用如下選項:type,default,required,validator
。import { Vue, Component, Prop } from 'vue-property-decorator' @Componentexport default class MyComponent extends Vue { @Prop(String) public propA: string | undefined @Prop([String, Number]) public propB!: string | number @Prop({ type: String, default: 'abc' }) public propC!: string }
等同於下面的js
寫法npm
export default { props: { propA: { type: Number }, propB: { default: 'default value' }, propC: { type: [String, Boolean] } } }
注意:element-ui
undefined
類型;或者在屬性名後面加上!,表示非null
和 非undefined
3,@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})promise
@PropSync
裝飾器與@prop
用法相似,兩者的區別在於:ide
@PropSync
裝飾器接收兩個參數:propName: string
表示父組件傳遞過來的屬性名;options: Constructor | Constructor[] | PropOptions
與@Prop
的第一個參數一致;@PropSync
會生成一個新的計算屬性。import { Vue, Component, PropSync } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { @PropSync('propA', { type: String, default: 'abc' }) public syncedPropA!: string }
等同於下面的js
寫法函數
export default { props: { propA: { type: String, default: 'abc' } }, computed: { syncedPropA: { get() { return this.propA }, set(value) { this.$emit('update:propA', value) } } } }
注意:@PropSync
須要配合父組件的.sync
修飾符使用ui
4,@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {})
@Model
裝飾器容許咱們在一個組件上自定義v-model
,接收兩個參數:
event: string
事件名。options: Constructor | Constructor[] | PropOptions
與@Prop
的第一個參數一致。import { Vue, Component, Model } from 'vue-property-decorator' @Component export default class MyInput extends Vue { @Model('change', { type: String, default: '123' }) public value!: string }
等同於下面的js
寫法
export default { model: { prop: 'value', event: 'change' }, props: { value: { type: String, default: '123' } } }
上面例子中指定的是change
事件,因此咱們還須要在template
中加上相應的事件:
<template> <input type="text" :value="value" @change="$emit('change', $event.target.value)" /> </template>
對自定義v-model
不太理解的同窗,能夠查看自定義事件
5,@Watch(path: string, options: WatchOptions = {})
@Watch
裝飾器接收兩個參數:
path: string
被偵聽的屬性名;options?: WatchOptions={} options
能夠包含兩個屬性 :immediate?:boolean
偵聽開始以後是否當即調用該回調函數;deep?:boolean
被偵聽的對象的屬性被改變時,是否調用該回調函數;
偵聽開始,發生在beforeCreate
勾子以後,created
勾子以前
import { Vue, Component, Watch } from 'vue-property-decorator' @Component export default class MyInput extends Vue { @Watch('msg') public onMsgChanged(newValue: string, oldValue: string) {} @Watch('arr', { immediate: true, deep: true }) public onArrChanged1(newValue: number[], oldValue: number[]) {} @Watch('arr') public onArrChanged2(newValue: number[], oldValue: number[]) {} }
等同於下面的js
寫法
export default { watch: { msg: [ { handler: 'onMsgChanged', immediate: false, deep: false } ], arr: [ { handler: 'onArrChanged1', immediate: true, deep: true }, { handler: 'onArrChanged2', immediate: false, deep: false } ] }, methods: { onMsgVhanged(newValue, oldValue) {}, onArrChange1(newValue, oldValue) {}, onArrChange2(newValue, oldValue) {} } }
6,@Emit(event?: string)
@Emit
裝飾器接收一個可選參數,該參數是$Emit
的第一個參數,充當事件名。若是沒有提供這個參數,$Emit
會將回調函數名的camelCase
轉爲kebab-case
,並將其做爲事件名;@Emit
會將回調函數的返回值做爲第二個參數,若是返回值是一個Promise
對象,$emit
會在Promise
對象被標記爲resolved
以後觸發;@Emit
的回調函數的參數,會放在其返回值以後,一塊兒被$emit
當作參數使用。import { Vue, Component, Emit } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { count = 0 @Emit() public addToCount(n: number) { this.count += n } @Emit('reset') public resetCount() { this.count = 0 } @Emit() public returnValue() { return 10 } @Emit() public onInputChange(e) { return e.target.value } @Emit() public promise() { return new Promise(resolve => { setTimeout(() => { resolve(20) }, 0) }) } }
等同於下面的js
寫法
export default { data() { return { count: 0 } }, methods: { addToCount(n) { this.count += n this.$emit('add-to-count', n) }, resetCount() { this.count = 0 this.$emit('reset') }, returnValue() { this.$emit('return-value', 10) }, onInputChange(e) { this.$emit('on-input-change', e.target.value, e) }, promise() { const promise = new Promise(resolve => { setTimeout(() => { resolve(20) }, 0) }) promise.then(value => { this.$emit('promise', value) }) } } }
7,@Ref(refKey?: string)
@Ref
裝飾器接收一個可選參數,用來指向元素或子組件的引用信息。若是沒有提供這個參數,會使用裝飾器後面的屬性名充當參數
import { Vue, Component, Ref } from 'vue-property-decorator' import { Form } from 'element-ui' @Componentexport default class MyComponent extends Vue { @Ref() readonly loginForm!: Form @Ref('changePasswordForm') readonly passwordForm!: Form public handleLogin() { this.loginForm.validate(valide => { if (valide) { // login... } else { // error tips } }) } }
等同於下面的js
寫法
export default { computed: { loginForm: { cache: false, get() { return this.$refs.loginForm } }, passwordForm: { cache: false, get() { return this.$refs.changePasswordForm } } } }
@Provide/@Inject 和 @ProvideReactive/@InhectReactive
因爲平時基本不用到provide/inject選項,暫時先放着,之後有時間再研究