Why use TypeScript (main reason)

1. Supersets of JavaScript

Support for all native JavaScript syntax

2. Strongly typed languages

Many of today’s major languages are strongly typed, and JavaScript has been criticized for this. With TypeScript, you save a lot of time debugging code, refactoring, and so on.

For example, if you want to understand the structure of the value, you need to read this code carefully. It’s handy to see the return value structure of a function with TypeScript

TypeScript configuration

1. Webpack

  • You need to install it firstts-loaderTypeScript provides a compiler for Webpack similar tobabel-loader
npm i ts-loader -D
Copy the code
  • Configure rules next in the Webpackmodule.rulesAdd support for TS (my webpack version is 2.x) :
{
    test: /\.vue$/.loader: 'vue-loader'.options: vueLoaderConfig
},
{
    test: /\.ts$/.loader: 'ts-loader'.options: {
      appendTsSuffixTo: [/\.vue$/].}}Copy the code
  • Add support for TS by configuring the extensions to identify file suffixes, such as:
extensions: ['.js'.'.vue'.'.json'.'.ts']
Copy the code

2. tsconfig.json

Create a tsconfig.json file in the root directory, the same as package.json

Configuration is up to you, and can be found on the typescript website, but there are a few things to note:

In Vue, you need to introduce strict: true (or at least noImplicitThis: True, which is part of strict mode) to take advantage of type checking for this in component methods, otherwise it will always be treated as any.

{
  "include": [
    "src/*"."src/**/*"]."exclude": [
    "node_modules"]."compilerOptions": {
    // types option has been previously configured
    "types": [
      // add node as an option
      "node"].// typeRoots option has been previously configured
    "typeRoots": [
      // add path to @types
      "node_modules/@types"].// Parse in strict mode
    "strict": true.// Support JSX in.tsx files
    "jsx": "preserve".// Use the JSX factory function
    "jsxFactory": "h".// Allow default imports from modules that do not have default exports set
    "allowSyntheticDefaultImports": true.// Enable the decorator
    "experimentalDecorators": true."strictFunctionTypes": false.// Allows javascript files to be compiled
    "allowJs": true.// The module system used
    "module": "esnext".// Compile the output target ES version
    "target": "es5".// How to handle modules
    "moduleResolution": "node".// There is an error with an implied any type on expressions and declarations
    "noImplicitAny": true."lib": [
      "dom"."es5"."es6"."es7"."es2015.promise"]."sourceMap": true."pretty": true}}Copy the code

3. Modify the main. Js

  • Put the project master filemain.jsModified intomain.ts, but there is one thing to note: when importing Vue files, you need to add.vueSuffix, otherwise the editor will not recognize
  • Change the entry file of webpack tomain.ts

4. vue-shims.d.ts

TypeScript doesn’t support Vue files, so you need to tell TypeScript*. Vue files to be handled by the Vue editor. The solution is to create a vue-shims.d.ts file, which can be placed in the root directory, the same level as package.json

*.d.ts type files do not need to be imported manually, TypeScript loads them automatically

declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}

Copy the code

5. Use of global variables

You declare the keyword to tell TypeScript that you are trying to express a code creation vue-shims.global.ts file that already exists somewhere else and can be placed in the root directory at the same level as package.json

declare let $:(select:string) = > any
declare let wx: any
interface Window {
    Bridge: any,
    _XT: any
}
Copy the code

6. Global/instance properties and methods, components of Vue

Create a vue-shims.option.ts file that can be placed in the root directory, the same level as package.json

import Vue from 'vue'
declare module 'vue/types/vue' {
    // You can use the VueConstructor interface
    // to declare global properties
    interface Vue {
        $axios: any,
        Login: (options? :any):void}}Copy the code

7. Additional declaration files are required when importing third-party libraries

Create vue-shims.d.ts file, which can be placed in the root directory, the same level as package.json

declare module 'vue-awesome-swiper' {
  export const swiper: any
  export const swiperSlide: any
}

declare module 'vue-lazyload'
Copy the code

Third-party plug-in library

vue-class-component

Vue-class-component is an officially maintained TypeScript decorator that is written flat

import  { Component, Vue, Watch, Prop  }  from 'vue-class-component'
import Header from '@/component/header.vue'
import MyMixin from './mixin.js'

Vue.mixin(MyMixin);

@Component({
    // component
    components:{ Header }
})
export default class App extends Vue {
    // initial data
    name:string = 'xiaowu'

    // computed
    get getMyName():string {
        return `my name is ${this.name}`
    }

    // props
    @Prop({
        default: '',
        type: [String, Number]
    })
    phone: [string, number];

    // method
    jumpPage():void{
        console.log('jump page')
    }

    // lifecycle hook
    mounted(){
        console.log('mounted !!)
    }

    // watch 
    @Watch('state', { deep: true })
    onStateChange(n: any, o: any) {
        console.log('state is change ')   
    }
}

Copy the code

How do I use routed hooks within a component

  • Create a new class-component-rests. ts file and import it in the import main.ts file
// Register the router hooks with their names
Component.registerHooks([
  'beforeRouteEnter'.'beforeRouteLeave'.'beforeRouteUpdate' / / for vue - 2.2 + router
])  
Copy the code

vuex-class

Vuex-class is based on a decorator provided for vuex based on vuE-class-Component. Its authors are also major contributors to vue-class-Component, and its quality is guaranteed.

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 MyComp extends Vue {
  @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
 
  created () {
    this.stateFoo // -> store.state.foo
    this.stateBar // -> store.state.bar
    this.getterFoo // -> store.getters.foo
    this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
    this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
    this.moduleGetterFoo // -> store.getters['path/to/module/foo']}}Copy the code