Typescript在Vue專案中用法
阿新 • • 發佈:2020-09-19
首先介紹typescript在vue中3中使用方式
1.class+裝飾器模式
<template> <div class="hello"> <h1>{{ msg }}</h1> <!-- 新增特性 --> <p><input type="text" @keydown.enter="addFeature"></p> <div>特性總數: {{count}}</div> </div> </template> <script lang="ts"> import { Component, Prop, Vue, Emit, Provide, Inject Watch } from 'vue-property-decorator' @Component({ // 註冊元件 components: { YouComponent } }) export default class HelloWorld extends Vue { // props使用方式 @Prop({ type: String, required: true, default: 'hello' }) private msg!: string; // data直接宣告,!為斷言,告訴ts將來這裡會傳值,讓ts不用操心 features: string[] = ['html', 'css', 'js'] // 生命週期正常使用就行 created() { console.log('create正常使用') } // get儲存器作為計算屬性 get count() { return this.features.length } // emit呼叫方式,向父元件傳遞資訊 —— 在父元件接受需要羊肉串命名法,add-feature @Emit() // @Emit如果想傳參就return一個值 addFeature (e: KeyboardEvent) { // 斷言:使用者確定變數的型別,可以使用斷言 const inp = e.target as HTMLInputElement this.features.push(inp.value) inp.value = '' return feature } // watch監聽features @Watch('features', { deep: true, immediate: true }) onFeaturesChange (val: any, old: any) { console.log('features變化了', val, old) } // 依賴注入的使用方式 @Provide() foo = 'foo' // 在父元件中提供foo // 在子元件中注入 @Inject() foo!: string } </script>
2.Vue.extend模式
<script lang="ts"> import Vue from 'vue' export default Vue.extend({ created () {}, data () { return { title: '使用ts的extend方法1 ' } }, methods: {}, watch: {}, computed: {}, }) </script>
這種模式和原來的寫法一樣,也會有ts的提示
3.tsx模式
import { Component, Vue } from 'vue-property-decorator' @Component export default class HelloWorld extends Vue { xianyu = 'tsx方式' add () { console.log(1) } render () { return ( <div> <span>{this.xianyu}</span> </div> ) } }
這種模式更適合於react的同學。模板位於class中,編寫模板是也會有提示
vuex-module-decorators 通過裝飾器提供模組化宣告vuex模組的方法,可以有效利用ts的型別系統。
安裝
npm i vuex-module-decorators -D
新增store根檔案store/index.ts
import Vuex from 'vuex' import Vue from 'vue' Vue.use(Vuex) // 這種方式為動態匯入模組,不需要配置Vuex.store // 也不需要在main.ts中引入 export default new Vuex.Store({ })
定義counter模組,建立store/counter.ts
import { Module, VuexModule, Mutation, Action, getModule } from 'vuex-module-decorators' import store from './index' // 動態註冊模組 @Module({ dynamic: true, store: store, name: 'counter', namespaced: true }) class CounterModule extends VuexModule { count = 1 @Mutation add () { // 通過this直接訪問count this.count++ } // 定義getters get doubleCount () { return this.count * 2 } @Action asyncAdd () { setTimeout(() => { // 通過this直接訪問add // this.context.commit('add') 等價於下面 this.add() }, 1000) } } // 匯出模組應該是getModule的結果 export default getModule(CounterModule)
使用方式,App.vue
<template> <div> <h1 @click="add">mutation:{{count}}</h1> <h1 @click="asyncAdd">action:{{count}}</h1> <h1>getter:{{doubleCount}}</h1> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator' import Counter from '@/store/counter' @Component export default class extends Vue { get count () { return Counter.count } get doubleCount () { return Counter.doubleCount } add () { Counter.add() } asyncAdd () { Counter.asyncAdd() } } </script>