vue2.x中使用typescript

本文目的在於你們能夠快速在vue中使用ts,關於ts的具體的使用方法,你們能夠去官網查看。 之前各種類型轉換的騷寫法寫習慣了,好比:html

const y = '5';
const x = + y;
複製代碼

然鵝在最近的項目中,因爲類型判斷引起的bug不在少數,好比A頁面跳轉B頁面帶的參數是個String類型,可是在B頁面會校驗這個參數是不是Number類型,由此出現問題,一頓猛找,最後一陣無語。 由此以爲vue中引入ts,應該會...真香

vue


下面就簡單介紹下vue中引入ts後具體的寫法有什麼不一樣了,以便你們能夠更爲快速的上手。 具體更爲詳細的使用方法你們能夠參考vue-property-decoratorvuex-module-decorators,至於引入ts的一些配置,這裏很少作贅述,有興趣的同窗能夠閒暇研究一下。vuex

話很少說,下面就進入正文部分

vue-property-decorator的經常使用示例

在vue-property-decorator中有如下幾個修飾符組成:npm

  • @Component
  • @Prop
  • @Model
  • @Emit
  • @Inject
  • @Provide
    下面以JS寫法和TS寫法做爲對比供你們參考

@Component

js寫法安全


 import { compA, compB } from '@/components'; export default { components: { compA, compB } } 複製代碼

ts寫法bash

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

export default class XXX extends Vue {
    ...
}
複製代碼

Prop

js寫法編輯器

export default {
   props: (
       propA: String,
       propB: [Number, String],
       propC: {
           default: 'default value'
       }
   )
}
複製代碼

ts寫法ide

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'}) readonly propC!: string   // 注意  這裏的!標識這個prop必定是非空的
}
複製代碼

@Model

js寫法函數

<my-comp v-model="checked" />  // 父組件引用
// 子組件
<input type="checkbox" @change="$emit('eventName', $event.target.checked)" :checked="checked">
export default {
    props: {
        checked: {
            type: Boolean
        }
    },
    model: {
        prop: 'checked',
        event: 'eventName'
    }
}
複製代碼

ts寫法工具

import {Vue, Component, Model} from 'vue-property-decorator';
@Component
export default class Myconponent extends Vue {
    @Model('eventName', {type: Boolean}) readonly checked!: boolean
}
複製代碼

@Watch

js寫法

export default {
    watch: {
        val1: [{
            handler: 'onValue1Change',
            immediate: false,
            deep: false
        }],
        val2: [{
            handler: 'onValue2Change',
            immediate: true,
            deep: true
        }]
    }
    
    methods: {
        onVal1Change(newVal, oldVal) {},
        onVal2Change(newVal, oldVal) {}
    }
}
複製代碼

ts寫法

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){}
}
複製代碼

inject && provide

js寫法

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

複製代碼

ts 寫法

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'
}
複製代碼

@Emit

js寫法

export default {
    methods: {
        addNumber(n) {
            this.$emit('eventName', n);
        },
        
        otherEvent(params) {
            this.$emit('other-event', params)
        }
    }
}
複製代碼

ts寫法

import {Vue, Component, Emit} from 'vue-property-decorator';
@Component
export default class MyComponent extends Vue {
    @Emit('eventName')
    addNumber(n: Number) {
        return n
    }
    
    @Emit()  // 若是不提供事件名 默認爲函數名  駝峯命名會被轉化爲kebab-case
    otherEvent(params: string) {
        return params
    }

}
複製代碼

計算屬性

js寫法

export default {
    computed: {
        val: function() {
            ...
            return xx
        }
    }
}
複製代碼

ts寫法

// 將該計算屬性名定義爲一個函數,並在函數前加上get關鍵字便可
import {Vue, Components} from 'vue-property-decorator'
@Component({})
export default class MyComponent {
    get val() {
        ...
        return xx
    }

}
複製代碼

以上就是vue中引入vue-property-decorator後的經常使用的一些示例。 平常開發中狀態管理工具在各模塊數據交互傳輸也起到很重要的做用,下面介紹下vuex-module-decorator

vuex-module-decorator的使用

state中定義namespace爲test的模塊

import { VuexModule, Module, Action, Mutation } from 'vuex-module-decorators'

// 待實現的state的接口
export 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() {
  // action中調用mutation
    this.addOne();
  }

  @Action
  private emitSubstract() {
    this.substract()
  }

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

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

}
複製代碼

store的使用
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)  // 經過getModule()安全訪問Store

@Component({});
export default class MyComponent extends Vue {
    public showStateData(): void {
    // 調用state中的data
        console.log(testModule.num)
    }
    // 調用action
    emitAction():void {
          testModule.emitAddOne()
      }
    // 調用mutation  
      emitMutation(): void {
        testModule.substract()
      }
}
複製代碼

優勢和不足

優勢挺多:

  • 清晰的函數參數/接口屬性,增長了代碼可讀性和可維護性
  • 靜態檢查
  • 生成API文檔
  • 配合現代編輯器,各類提示
  • 活躍的社區
    缺點也有:
  • 和某些庫結合的不是很完美(沒錯,說的就是vue 2.x)

這裏提到的vue2.x因爲ts先天能力的不足,致使vue的ts語法須要使用class風格(運行時會被轉換回本來的vue構造函數的語法),和咱們平時熟悉的vue風格有些差別

最後

ts帶上vue-property-decorator和vuex-module-decorator,開始愉快的開發吧~

相關文章
相關標籤/搜索