一,装置

npm i -s vue-property-decorator 

二,用法

1,@Component(options:ComponentOptions = {})

@Component 装璜器能够接管一个对象作为参数,能够在对象中申明 components ,filters,directives等未提供装璜器的选项,也能够申明computed,watch

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) = {})

@Prop装璜器接管一个参数,这个参数能够有三种写法:

  • 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写法

export default {  props: {    propA: {      type: Number    },    propB: {      default: 'default value'    },    propC: {      type: [String, Boolean]    }  }} 

留神:

  • 属性的ts类型前面须要加上undefined类型;或者在属性名前面加上!,示意非null非undefined
    的断言,否则编译器会给出谬误提醒;
  • 指定默认值必须应用下面例子中的写法,如果间接在属性名前面赋值,会重写这个属性,并且会报错。

3,@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})

@PropSync装璜器与@prop用法相似,二者的区别在于:

  • @PropSync 装璜器接管两个参数:
    propName: string 示意父组件传递过去的属性名;
    options: Constructor | Constructor[] | PropOptions@Prop的第一个参数统一;
  • @PropSync 会生成一个新的计算属性。
import { Vue, Component, PropSync } from 'vue-property-decorator'@Componentexport 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修饰符应用

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'@Componentexport 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'@Componentexport 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'@Componentexport 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选项,临时先放着,当前有工夫再钻研

参考:https://github.com/kaorun343/...