Currently, in projects developed with vue, TypeScript will be used to perform some constraints. In order to improve development efficiency, it is often usedDecorators
To simplify our code.
This article mainly introduces decoratorsvue-property-decorator
and vux-class
Use of
1. Installation
npm i -S vue-property-decorator npm i -S vuex-class
2. vue-property-decorator
@Component
@Prop
@PropSync
@Model
@ModelSync
@Watch
@Provide
@Inject
@ProvideReactive
@InjectReactive
@Emit
@Ref
@VModel
@Component
import { Vue, Component } from 'vue-property-decorator' @Component({ components:{ componentA, componentB, } }) export default class MyComponent extends Vue{ }
Equivalent to:
export default{ name: 'MyComponent', components:{ componentA, componentB, } }
@Prop
@Prop(options: (PropOptions | Constructor[] | Constructor) = {}) decorator
express:@Prop
The decorator receives a parameter, which can be written in three ways:
- PropOptions: The following options can be used: type, required, default, validator
- Constructor: For example, String, Number, Boolean, etc., specify the type of prop
- Constructor[]: Specify the optional type of prop
For example:
import { Vue, Component, Prop } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { @Prop(Number) readonly propA: number | undefined @Prop({ default: 'default value' }) readonly propB!: string @Prop([String, Boolean]) readonly propC: string | boolean | undefined }
Equivalent to:
export default { name: 'MyComponent', props: { propA: { type: Number, }, propB: { default: 'default value', }, propC: { type: [String, Boolean], }, },
@PropSync
@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator
- propName represents the attribute name passed by the parent component
- Parent components need to be combined
.sync
Come to use
For example:
// import { Vue, Component, PropSync } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { @PropSync('name', { type: String }) syncedName!: string
<!-- --> <template> <div> <MyComponent :="name" /> </div> </template>
Equivalent to:
export default { name: 'MyComponent', props: { name: { type: String, }, }, computed: { syncedName: { get() { return }, set(value) { this.$emit('update:name', value) }, }, }, }
@PropSync
Working principle and@Prop
Similarly, in addition to accepting propName as the decorator parameter, it also creates a computed getter and setter behind the scenes. This way you can use the property as you would with a regular data property, while adding it in the parent component.sync
Modifiers are as simple as that.
@Model
@Model
The decorator allows us to customize the v-model on a component.
@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator
For example:
import { Vue, Component, Model } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { @Model('change', { type: Boolean }) readonly checked!: boolean }
Equivalent to:
export default { model: { prop: 'checked', event: 'change', }, props: { checked: { type: Boolean, }, }, }
@ModelSync
@ModelSync(propName: string, event?: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator
For example:
import { Vue, Component, ModelSync } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { @ModelSync('checked', 'change', { type: Boolean }) readonly checkedValue!: boolean }
Equivalent to:
export default { model: { prop: 'checked', event: 'change', }, props: { checked: { type: Boolean, }, }, computed: { checkedValue: { get() { return }, set(value) { this.$emit('change', value) }, }, }, }
@Watch
@Watch(path: string, options: WatchOptions = {}) decorator
For example:
import { Vue, Component, Watch } from 'vue-property-decorator' @Component export default class MyComponent 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) {} }
Equivalent to:
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) {}, }, }
@Provide
| @Inject
@Provide(key?: string | symbol) decorator @Inject(options?: { from?: InjectKey, default?: any } | InjectKey) decorator
For example:
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' }
Equivalent to:
const symbol = Symbol('baz') export const MyComponent = ({ inject: { foo: 'foo', bar: 'bar', optional: { from: 'optional', default: 'default' }, baz: symbol, }, data() { return { foo: 'foo', baz: 'bar', } }, provide() { return { foo: , bar: , } }, })
@ProvideReactive
| @InjectReactive
They are@provider
and@Inject
responsive version of . If the parent component modifies the provided value, the child component can capture this modification.
@ProvideReactive(key?: string | symbol) decorato @InjectReactive(options?: { from?: InjectKey, default?: any } | InjectKey) decorator
For example:
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 }
@Emit
@Emit(event?: string) decorator
For example:
import { Vue, Component, Emit } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { count = 0 @Emit() addToCount(n: number) { += n } @Emit('reset') resetCount() { = 0 } @Emit() returnValue() { return 10 } @Emit() onInputChange(e) { return } @Emit() promise() { return new Promise((resolve) => { setTimeout(() => { resolve(20) }, 0) }) } }
Equivalent to:
export default { data() { return { count: 0, } }, methods: { addToCount(n) { += n this.$emit('add-to-count', n) }, resetCount() { = 0 this.$emit('reset') }, returnValue() { this.$emit('return-value', 10) }, onInputChange(e) { this.$emit('on-input-change', , e) }, promise() { const promise = new Promise((resolve) => { setTimeout(() => { resolve(20) }, 0) }) ((value) => { this.$emit('promise', value) }) }, }, }
@Ref
Ref(refKey?: string) decorator
For example:
import { Vue, Component, Ref } from 'vue-property-decorator' import AnotherComponent from '@/path/to/' @Component export default class MyComponent extends Vue { @Ref() readonly anotherComponent!: AnotherComponent @Ref('aButton') readonly button!: HTMLButtonElement }
Equivalent to:
export default { computed() { anotherComponent: { cache: false, get() { return this.$ as AnotherComponent } }, button: { cache: false, get() { return this.$ as HTMLButtonElement } } } }
@VModel
@VModel(propsArgs?: PropOptions) decorator
For example:
import { Vue, Component, VModel } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { @VModel({ type: String }) name!: string }
Equivalent to:
export default { props: { value: { type: String, }, }, computed: { name: { get() { return }, set(value) { this.$emit('input', value) }, }, }, }
3. vuex-class
@State
@Getter
@Action
@Mutation
namespace
import Vue from 'vue' import Component from 'vue-class-component' import { State, Getter, Action, Mutation, namespace } from 'vuex-class' const someModule = namespace('path/to/module') @Component export class MyComponent extends Vue { @State('foo') stateFoo @State(state => ) stateBar @Getter('foo') getterFoo @Action('foo') actionFoo @Mutation('foo') mutationFoo @('foo') moduleGetterFoo // If the parameters are omitted, use the attribute name of each state/getter/action/mutation type directly @State foo @Getter bar @Action baz @Mutation qux created () { // -> // -> // -> ({ value: true }) // -> ('foo', { value: true }) ({ value: true }) // -> ('foo', { value: true }) // -> ['path/to/module/foo'] } }
This is the article about the detailed explanation of vue-property-decorator and vux-class in Vue decorator. For more related vue-property-decorator and vux-class content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!