首先介紹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>
