The purpose of this article is that you can quickly use TS in VUE. You can go to the official website for detailed usage of TS. Previous types of conversion of the SAO writing method to write habits, such as:

const y = '5';
const x = + y;
Copy the code

However, in the recent project, there are many bugs caused by type judgment. For example, when page A jumps to page B, the parameter with the type of String is checked, but the parameter with the type of Number is verified on page B, so there is A problem. It follows that the introduction of TS in VUE should… delicious


Here is a brief introduction to vUE after the introduction of TS specific writing method is different, so that you can more quickly start. See vue-property-decorators and vuex-module-decorators for more details on how to use the vue-property-decorator and vuex-module-decorators.

A common example of vue-property-decorator

A vue-property-decorator consists of the following decorators:

  • @Component
  • @Prop
  • @Model
  • @Emit
  • @Inject
  • @Provide The following is a comparison between JS and TS for your reference

@Component

Js writing



import { compA, compB } from '@/components';
export default {
    components: {
        compA,
        compB
    }
}
Copy the code

Ts writing

import {Component,Vue} from 'vue-property-decorator';
import {compA,comptB} from '@/components';
@Component({
    components: {
        compA,
        compB
    }
})

export default class XXX extends Vue {
    ...
}
Copy the code


Prop

Js writing

export default {
   props: (
       propA: String,
       propB: [Number, String],
       propC: {
           default: 'default value'})}Copy the code

Ts writing

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

@Component
export default class MyComponent extends Vue {
    @Prop(String) readonly propA: String | undefined
    @Prop([String, Number]) readonly propB: number | string | undefined
    @Prop({default: 'default value'}) readonlypropC! : string // Notice here! Indicates that this prop must be non-empty}Copy the code

@Model

Js writing

<my-comp v-model="checked"/> // Parent component reference // child <inputtype="checkbox" @change="$emit('eventName', $event.target.checked)" :checked="checked">
export default {
    props: {
        checked: {
            type: Boolean
        }
    },
    model: {
        prop: 'checked',
        event: 'eventName'}}Copy the code

Ts writing

import {Vue, Component, Model} from 'vue-property-decorator';
@Component
export default class Myconponent extends Vue {
    @Model('eventName', {type: Boolean}) readonlychecked! : boolean }Copy the code

@Watch

Js writing

export default {
    watch: {
        val1: [{
            handler: 'onValue1Change',
            immediate: false,
            deep: false
        }],
        val2: [{
            handler: 'onValue2Change',
            immediate: true,
            deep: true
        }]
    }
    
    methods: {
        onVal1Change(newVal, oldVal) {},
        onVal2Change(newVal, oldVal) {}
    }
}
Copy the code

Ts writing

import {Vue, Component, Watch} from 'vue-property-decorator';
@Component
export default class MyComponent extends Vue {
    @Watch('val1')
    onVal1Change(newVal, oldVal){}
    
    @Watch('val2', {immediate: true, deep: true})
    onVal2Change(newVal, oldVal){}
}
Copy the code


inject && provide

Js writing

import {Vue, Component, Model, Inject} from 'vue-property-decorator'
const symbol = Symbol('baz')

@Component
export default class MyComponent extends Vue {
    inject: {
        foo: 'foo',
        bar: 'bar',
        optional: { from: 'optional', default: 'default' },
        [symbol]: symbol
    },
    
    data() {
        return {
            foo: 'foo',
            baz: 'bar'}},provide() {
        return {
            foo: this.foo,
            baz: this.baz
        }
    }
}

Copy the code

Ts writing

import { Component, Inject, Provide, Vue } from 'vue-property-decorator'
 
const symbol = Symbol('baz')
 
@Component
export class MyComponent extends Vue {
  @Inject() readonlyfoo! : string @Inject('bar') readonlybar! : string @Inject({ from:'optional', default: 'default' }) readonlyoptional! : string @Inject(symbol)readonlybaz! : string @Provide() foo ='foo'
  @Provide('bar') baz = 'bar'
}
Copy the code

@Emit

Js writing

export default {
    methods: {
        addNumber(n) {
            this.$emit('eventName', n);
        },
        
        otherEvent(params) {
            this.$emit('other-event', params)
        }
    }
}
Copy the code

Ts writing

import {Vue, Component, Emit} from 'vue-property-decorator';
@Component
export default class MyComponent extends Vue {
    @Emit('eventName')
    addNumber(n: Number) {
        returnN} @emit () // If the event name is not provided by default the function name will be converted to kebab-case otherEvent(params: string) {return params
    }

}
Copy the code


Calculate attribute

Js writing

export default {
    computed: {
        val: function() {...return xx
        }
    }
}
Copy the code

Ts writing

Import {Vue, Components} from import {Vue, Components} from import {Vue, Components} from'vue-property-decorator'
@Component({})
export default class MyComponent {
    get val() {...return xx
    }

}
Copy the code

These are some examples of common vUE property-decorators introduced in VUE. Vuex-module-decorator state management tools also play an important role in the interaction between modules

The use of vuex – the module – the decorator

State defines the module with a namespace of Test

import { VuexModule, Module, Action, Mutation } from 'vuex-module-decorators'// The interface of the state to be implementedexport interface TestState {
  num: number,
  firstName: string
}

// 
@Module({namespaced: true, name: 'test', stateFactory: true})

export default class Test extends VuexModule implements TestState {
// state
  public num = 0;
  public firstName = ' ';

  @Action
  public emitAddOne() {// call mutation this.addone () in action; } @Action privateemitSubstract() {
    this.substract()
  }

  @Mutation
  private addOne() {
    this.num ++;
  }

  @Mutation
  private substract() {
    this.num --;
  }
  
  // getters
  get addNum() {
    return this.num ++
  }

}
Copy the code


import { Vue, Component } from 'vue-property-decorator';
import { getModule } from 'vuex-module-decorator';
import test from '@/store/module/Test';
import store from '@/store/index'

const testModule = getModule(test, store) // Secure access to Store @Component({}) with getModule();exportDefault class MyComponent extends Vue {public showStateData(): void {// Call state data console.log()testModule.num)} // Call action emitAction():void {testModule.emitaddone ()} // call mutation emitMutation(): void {testModule.substract()
      }
}
Copy the code

Advantages and disadvantages

There are many advantages:

  • Clear function parameters/interface attributes, increase code readability and maintainability
  • Static checking
  • Generating API documentation
  • With modern editor, various tips
  • Active communities also have disadvantages:
  • Doesn’t work perfectly with some libraries (yes, vue 2.x)

Vue’s ts syntax needs to use the class style (which will be converted back to the original Vue constructor syntax at runtime), which is somewhat different from the familiar Vue style

The last

Ts put on vue-property-decorator and vuex-module-decorator and have fun