(翻譯)vue-property-decorator

vue-property-decorator

本文翻譯自 vue-property-decorator

這個庫徹底依賴 vue-class-component 庫棉胀,請在使用這個庫之前先閱讀它的 readme

安裝

npm i -S vue-property-decorator

用法

這里有一些修飾器(decorators)以及一個函數(shù)(Mixin)
@Prop
@PropSync
@Model
@Watch
@Provide
@Inject
@ProvideReactive
@InjectReactive
@Emit
@Ref
@Component (由 vue-class-component 提供)
Mixins (幫助函數(shù) mixins 由 vue-class-component 提供)

另請查閱

(vuex-class)[https://github.com/ktsn/vuex-class/]

<a id="Prop"></a> @Prop(options: (PropOptions | Constructor[] | Constructor) = {})修飾器

import { Vue, Component, Prop } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @Prop(Number) readonly propA: number | undefined
  @Prop({ default: 'default value' }) readonly propB!: string
  @Prop([String, Boolean]) readonly propC: string | boolean | undefined
}

等同于

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

注意:
如果你想要通過 type 設置給每個 prop 值設置 type 屬性,你可以使用 reflect-metadata

1.設置 emitDecoratorMetadatatrue
2.在引入 vue-property-decorator 之前引入 reflect-metadata(只需要引入一次)

import 'reflect-metadata'
import { Vue, Component, Prop } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  @Prop() age!: number
}

每個 prop 的默認值必須向上面這樣定義

不支持像這樣定義默認值:@Prop() prop = 'default value'

<a id="PropSync"></a> @PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator

import { Vue, Component, PropSync } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @PropSync('name', { type: String }) syncedName!: string
}

等同于:

export default {
  props: {
    name: {
      type: String
    }
  },
  computed: {
    syncedName: {
      get() {
        return this.name
      },
      set(value) {
        this.$emit('update:name', value)
      }
    }
  }
}

不同于僅僅像 @Prop 一樣工作召廷,也不同于僅僅是把 propName 當做修飾器的參數(shù)绵患,它還自動進一步幫我們創(chuàng)建了一個計算屬性的 getter 和 setter雾叭,通過這樣的方式,你可以像 data 屬性一樣使用這個屬性藏雏,與此同時拷况,我們只需要在父組件添加 .sync 修飾符

<a id="Model"></a> @Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator

import { Vue, Component, Model } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @Model('change', { type: Boolean }) readonly checked!: boolean
}

等同于:

export default {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: {
      type: Boolean
    }
  }
}

@Model 屬性也可以通過 reflect-metadata 來設置默認類型

<a id="Watch"></a> @Watch(path: string, options: WatchOptions = {}) decorator

import { Vue, Component, Watch } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @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) {}
}

等同于

export default {
  watch: {
    child: [
      {
        handler: 'onChildChanged',
        immediate: false,
        deep: false
      }
    ],
    person: [
      {
        handler: 'onPersonChanged1',
        immediate: true,
        deep: true
      },
      {
        handler: 'onPersonChanged2',
        immediate: false,
        deep: false
      }
    ]
  },
  methods: {
    onChildChanged(val, oldVal) {},
    onPersonChanged1(val, oldVal) {},
    onPersonChanged2(val, oldVal) {}
  }
}

<a id="Provide"></a><a id="Inject"></a> @Provide(key?: string | symbol) / @Inject(options?: { from?: InjectKey, default?: any } | InjectKey) decorator

import { Component, Inject, Provide, Vue } from 'vue-property-decorator'

const symbol = Symbol('baz')

@Component
export class MyComponent extends Vue {
  @Inject() readonly foo!: string
  @Inject('bar') readonly bar!: string
  @Inject({ from: 'optional', default: 'default' }) readonly optional!: string
  @Inject(symbol) readonly baz!: string

  @Provide() foo = 'foo'
  @Provide('bar') baz = 'bar'
}

等同于

const symbol = Symbol('baz')

export const MyComponent = 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
    }
  }
})

<a id="ProvideReactive"></a><a id="InjectReactive"></a> @ProvideReactive(key?: string | symbol) / @InjectReactive(options?: { from?: InjectKey, default?: any } | InjectKey) decorator

這個是 @Provide@Inject的響應式版本,如果一個提供(provide)的值在父組件修改了掘殴,子組件可以捕捉到這些更改

const key = Symbol()
@Component
class ParentComponent extends Vue {
  @ProvideReactive() one = 'value'
  @ProvideReactive(key) two = 'value'
}

@Component
class ChildComponent extends Vue {
  @InjectReactive() one!: string
  @InjectReactive(key) two!: string
}

<a id="Emit"></a> @Emit(event?: string) decorator

@Emit 修飾的函數(shù)赚瘦,會 $emit 它返回的值,以及它的參數(shù)(放在返回值后面)奏寨,如果返回的是一個 promise起意,會先 resolved 再觸發(fā)事件。
如果 @Emit 后面沒有跟著事件名作為參數(shù)病瞳,函數(shù)名會作為事件名稱揽咕,在這種情況下,駝峰式的名字會被改為短橫線隔開式(kebab-case)

import { Vue, Component, Emit } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  count = 0

  @Emit()
  addToCount(n: number) {
    this.count += n
  }

  @Emit('reset')
  resetCount() {
    this.count = 0
  }

  @Emit()
  returnValue() {
    return 10
  }

  @Emit()
  onInputChange(e) {
    return e.target.value
  }

  @Emit()
  promise() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve(20)
      }, 0)
    })
  }
}

等同于

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

<a id="Ref"></a> @Ref(refKey?: string) decorator

import { Vue, Component, Ref } from 'vue-property-decorator'

import AnotherComponent from '@/path/to/another-component.vue'

@Component
export default class YourComponent extends Vue {
  @Ref() readonly anotherComponent!: AnotherComponent
  @Ref('aButton') readonly button!: HTMLButtonElement
}

等同于

export default {
  computed() {
    anotherComponent: {
      cache: false,
      get() {
        return this.$refs.anotherComponent as AnotherComponent
      }
    },
    button: {
      cache: false,
      get() {
        return this.$refs.aButton as HTMLButtonElement
      }
    }
  }
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末套菜,一起剝皮案震驚了整個濱河市亲善,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逗柴,老刑警劉巖蛹头,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡渣蜗,警方通過查閱死者的電腦和手機屠尊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耕拷,“玉大人讼昆,你說我怎么就攤上這事∩眨” “怎么了浸赫?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長止潘。 經(jīng)常有香客問我掺炭,道長,這世上最難降的妖魔是什么凭戴? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任涧狮,我火速辦了婚禮,結果婚禮上么夫,老公的妹妹穿的比我還像新娘者冤。我一直安慰自己,他們只是感情好档痪,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布涉枫。 她就那樣靜靜地躺著,像睡著了一般腐螟。 火紅的嫁衣襯著肌膚如雪愿汰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天乐纸,我揣著相機與錄音衬廷,去河邊找鬼。 笑死汽绢,一個胖子當著我的面吹牛吗跋,可吹牛的內容都是我干的。 我是一名探鬼主播宁昭,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼跌宛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了积仗?” 一聲冷哼從身側響起疆拘,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寂曹,沒想到半個月后入问,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丹锹,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年芬失,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匾灶。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡棱烂,死狀恐怖,靈堂內的尸體忽然破棺而出阶女,到底是詐尸還是另有隱情颊糜,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布秃踩,位于F島的核電站衬鱼,受9級特大地震影響,放射性物質發(fā)生泄漏憔杨。R本人自食惡果不足惜鸟赫,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望消别。 院中可真熱鬧抛蚤,春花似錦、人聲如沸寻狂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛇券。三九已至缀壤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纠亚,已是汗流浹背塘慕。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留菜枷,地道東北人苍糠。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像啤誊,于是被迫代替她去往敵國和親岳瞭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容