はじめに
Vue + TypeScript の組み合わせでVueを書くときに、vue-property-decorator
を利用して書いていくことが多いと思います。
ただ vue-property-decorator
を利用すると、どうしてもVueらしさがなくなるというか、よりTypeScriptにらしい書き方になると感じています。
せっかくJavaScriptでVue書けるようになったのに、全然書き方が違うじゃないか…と挫折しかけることもあるんじゃないでしょうか?
ちなみに私は vue-property-decorator
で書くほうが慣れているので好きですが、Vue入門者には厳しいところがあると思うので、 Vue.extend
ベースでTypeScriptを書いていくという方法を紹介するのと、その際の型宣言についてもまとめていこうと思います。
VueをTypeScriptで書きたいけど、 vue-property-decorator
は使いたくない…って人の参考になればいいなーと思います。
Vue.extend ??
TypeScript内でVueモジュールをimport/extendして書く方法です。
JavaScriptでのVueコンポーネントの記述に近い書き方でTypeScriptを書くことができます。
<script lang="ts">
import Vue from "vue"
export default Vue.extend({
name: "component",
data() {
return {
value: "hoge"
}
}
})
</script>
環境構築
VueCLIで簡単に構築することができます。
TypeScriptを選択して、class-styleコンポーネントシンタックスを利用しないと選択すればいいです。
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection)
◯ Babel
❯◉ TypeScript
◯ Progressive Web App (PWA) Support
◯ Router
◯ Vuex
◯ CSS Pre-processors
◯ Linter / Formatter
◯ Unit Testing
◯ E2E Testing
? Use class-style component syntax? (Y/n) n
これで Vue.extend
の環境が構築されます。簡単ですね。
Vue.extend における型
Vue.extend ベースでTypeScriptで書いていく際の型宣言を紹介していこうと思います。
props
Propについてはネイティブコンストラクターを付与することで、内部で型推論されます。
またArrayやObjectの詳細な型宣言については PropType
を利用することで宣言することができます。
<script lang="ts">
import Vue, { PropType } from "vue"
export type PropObjType = {
id: string
index: number
}
export default Vue.extend({
props: {
val: {
type: String,
default: ""
},
obj: {
type: Object as PropType<PropObjType>,
default: () => ({
id: "",
index: 0
})
}
}
})
</script>
ここで注意が必要なのが、ビルド時のコンパイルエラーを得ることができないという点です。ただ実行時のエラーを得ることはできます。
また用意されているネイティブコンストラクターは以下の通りです。
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
data
data()関数に向けて型を定義し、型アノテーションを付与します。
<script lang="ts">
import Vue from "vue"
export type DataType = {
value: string
enable: boolean
count: number
}
export default Vue.extend({
data(): DataType {
return {
value: "hoge",
enable: true,
count: 0
}
}
})
</script>
lifecycle hooks
lifecycle hooksで着火するイベントは基本的に void
型の関数
<script lang="ts">
import Vue from "vue"
export default Vue.extend({
created(): void {
console.log("Created!!!")
}
})
</script>
computed
computedで呼び出される関数が返す値に対する型を宣言する
<script lang="ts">
import Vue from "vue"
export type DataType = {
value: string
enable: boolean
count: number
}
export default Vue.extend({
data(): DataType {
return {
value: "hoge",
enable: true,
count: 0
}
},
computed: {
isEnabled(): boolean {
return this.enable
},
getCount(): number {
return this.count
}
},
})
</script>
methods
methodsで呼び出される関数が返す値に対する型を宣言する
<script lang="ts">
import Vue from "vue"
export type DataType = {
value: string
enable: boolean
count: number
}
export default Vue.extend({
data(): DataType {
return {
value: "hoge",
enable: true,
count: 0
}
},
methods: {
countUp(): void {
this.count += 1
},
getValue(): string {
return this.value
}
}
})
</script>
まとめ
- Vueらしさを保ちつつTypeScriptで書きたいって人 → Vue.extend
- VueらしさよりTypeScriptらしく書きたいって人 → vue-property-decorator
という感じかなって思います。自分に合った方法でより楽しくVueを書いていきましょう!
ではまた!!!