Since UVU released vUE support for typescript in September of last year, we have been trying to get out of the box. The smoothness of VUE and the object-oriented orientation of TS for the sr front end are very nice to think about. Finally, two months ago, WE found an opportunity to try a combination of VUE and TS. The openers document the vUE and TS integration journey and some of the potholes encountered.

vue

Most of you probably know vUE, since vUE and React exist side by side today, so we won’t talk about it much.

The tutorial on vUE Chinese official website is the best introductory tutorial

typescript

I’ve been talking about typescript in the last few posts, but just to give a quick list of the benefits of TS

  1. From JavaScript to JavaScript,typescript is a superset of JavaScript, so it can reuse JavaScript code and use JavaScript libraries

  2. It has all the advantages of JavaScript, cross-browser, cross-operating system, etc

  3. Object-oriented programming ideas, powerful type checking

  4. Open source is good

If there is a downside, it is not suitable for small projects.

With these advantages, enough for us to play happily ~

Ts to install

Install Node first and then install the TS package via NPM

npm install -g typescript

Tsc-v Displays the TS version

Create a project

We will create the project through the official scaffolding vue-CLI

Install scaffolding and create projects

  1. Executing installation Commands

npm install -g @vue/cli

Once installed, you can quickly create scaffolding for a new project with Vue Create or prototype new ideas directly from Vue Serve.

  1. Create a projectvue create vue-tsVue-ts is the name of our project, executed as follows

Xiaoli is an option that I created earlier and will introduce later. “Default” says Babel eslint, meaning that if this is selected, only Babel and ealint will be introduced; Manually select features, as the name implies, choose what we want. So let’s pick the third one

As you can see, there are a lot of options in the list. We prefer vue+ TS, so we choose Babel typescript Router vuex

Last step, Save this as a preset for future projects? Selecting Yes stores our previous selections as a default option for subsequent one-click creation of new projects. After all steps are selected, press Enter to create the project file structure and pull the NPM package

The project structure

The project structure is as follows

index.html

SRC: Store vUE project engineering files, which have helped us associate router and VUEX, and the file structure is very simple

Others: Configuration files such as Webpack and Babel

With the typescript taking

Vue-class-component has been introduced under construction for TS support, or vue-property-decorator, which is an extension of the previous library.

Here are some variations of tsvue

Component declarations

The way to create a component becomes the following

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

@Component
export default class Test extends Vue {

}
Copy the code

The data object

The constructor creates the data in data

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

@Component
export default class Test extends Vue {
    private name: string;
    constructor() {
        super(a);this.name = 'xiaoli'; }}Copy the code

The data in data can be used as follows

public getName(){
    return this.name
}
Copy the code

Prop the statement

@Prop(a)public msg: string;
@Prop({ default: 'default value' }) propB: string
@Prop([String.Boolean]) propC: string | boolean
Copy the code

The lifecycle function is used

public created(): void {
    console.log('created');
}

public mounted():void{
    console.log('mounted')}Copy the code

Custom methods

Declare a method in a method object

public clickFunc(): void {
    console.log(this.name)
    console.log(this.msg)
}
Copy the code

Watch Listening property

@Watch('name',{ immediate: true, deep: true })
public onChildChanged(val: string, oldVal: string) {
    console.log('watch new name=' + val);
}
Copy the code

Computed properties

public get allname() {
    return 'computed ' + this.name;
}
Copy the code

Allname is the computed value and name is the listened value

Emit events

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

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

The first event is named add-to-count, where n is the passed parameter. The second event is called reset-count and the parameter is null

Instructions and filters

———- a little update —————

Some friends ask how instructions and filters are written under TS. I missed them before, so I would like to add them now.

I tried, and found that the previous method of directly introducing instructions or filters in the entry file did not work, because after USING TS, the scope of the component was different from the previous one. Then I found the official issue, as shown in the screenshot below

The author acknowledged this problem in his reply on April 11th, but it is unknown exactly when the instructions and filter declarations will be added, but the author gave a solution in the issue. Let me write a simple chestnut

A custom directive

// ./directive/index.ts
export const focus = {
    // When the bound element is inserted into the DOM...
    inserted: function (el:HTMLElement) {
        // Focus elements
        el.focus()
      }
}
Copy the code

A filter

// ./filter/index.ts
export const capitalize = function (value:string) {
    if(! value)return ' '
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)}Copy the code

Use in components

import { capitalize }from '@/filter/index'
import { focus } from '@/directive/index'
@Component({
    filters:{capitalize},
    directives:{focus}
})
export default class Test extends Vue {}
Copy the code
<div>
    <input v-focus v-model="modelData">
    <div>{{modelData | capitalize}}</div>
</div>
Copy the code

This is a local reference, but the global reference is not yet found, welcome to have a solution to the small friends

The mashup of VUex and TS

Vuex is listed separately because it is optional. First you need to reference the vuex-class library, which has the following modules

import {
    namespace,
    Action,
    Getter,
    Mutation,
    State
} from 'vuex-class';
Copy the code

They correspond to action, getter, mutation, etc., in VUEX. The influence of TS on VUEX mainly lies in the invocation of VUex by components. The definition of VUex should be defined in the previous way

@State('foo') stateFoo
@State(state= > state.bar) stateBar
@Getter('foo') getterFoo
@Action('foo') actionFoo
@Mutation('foo') mutationFoo
@someModule.Getter('foo') moduleGetterFoo

// If the argument is omitted, use the property name
// for each state/getter/action/mutation type
@State foo
@Getter bar
@Action baz
@Mutation qux
Copy the code

If you don’t want to use vuex’s method name, you can use a custom attribute name, as it is defined on this, so just use this

this.getterFoo // -> store.getters.foo
this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
Copy the code

summary

Once built, you can use the front end just like the back end