Vue3.xのCompositionAPIとTypeScriptの書き方
そろそろVue3.xが出るかもなので、目玉機能のCompositionAPIを試してみてまとめてみる。
TypeScript
Vue3.xxでは、TypeScript対応!!
やったー🎉🎉🎉🎉
composition api is 何?
ドキュメントは以下 https://vue-composition-api-rfc.netlify.com/
今までのVue2だと
- 肥大化していくと可読性が悪い
- コンポーネントのロジックの再利用性がつらみ
- TypeScript書きづらい。
- テスト書きにくい
みたいなことがあった。
これをReact hooksをヒントに新たにAPIを作成したものがcomposition api。
TypeScript対応だと現状vue-property-decoratorでデコレータ使うか、vue.extend
の2択しかないが、これだとアノテーション(型推論)の恩恵を受けづらいという問題もあった。
vue.extendを使う場合
TypeScript のサポートの通りだが、importをVue
から行いExtendVueオブジェクトを返すメソッドをexportすれば使用可能。(もちろんlang=“ts”もする。)
基本的にcomponents
以外のライフサイクルフックに型を定義していく。
// JavaScript
data() {
retrun {
text: 'text',
price: 120
}
}
// TypeScript
// 最初に型を作る
export type DataItem = {
text: String
price: Number
}
data(): DataItem {
retrun {
text: 'text',
price: 120
}
}
methods,computedなどはそれぞれの関数に型をつけていく ※公式ドキュメント通り
methods: {
greet (): string {
return this.msg + ' world'
}
},
computed: {
greeting(): string {
return this.greet() + '!'
}
}
導入のハードルがもっとも低いが細かい所まで型推論できなそう。
デコレータを使うやり方
JavaScriptのclassを用いたクラスベースの書き方。
vue-property-decoratorで必要なものをimportする。
使わない場合も一応書けるが、propsなどがちょっと見にくい感じになるので導入している所が多い。
import Vue from 'vue'
import {型指定したいもの Component, Vueなど} from 'vue-property-decorator'
componentsは、@Component({})
で囲う。
@Component({
AddButton
})
componentsがない場合は@Componentと書けばOK
その他は、export default class {{Name}} extends Vue {}
と記述。それぞれの処理を書いていく。
この時点で、だいぶシンタックスが変わるが以下のように記述していく。
// data() リアクティブになる。
message: string = 'message';
price: Number = 1230
// propsは@Propを使用する。複数の場合は都度使っていく
// JS
props: {
text: {
type: String,
default: ""
}
}
//TS
@Prop({ default: "" }) text!: string
watch, computed, methods
サンプルコード書かないが以下の様な形
- watchは@Watchとしてデコレータする
- computedはクラス構文のgetterメソッドで定義する。
- methodsはそのままクラス構文の中で使用可能。
※Vue3のRFCによると非推奨の書き方になるようで、今からプロジェクト始める場合は導入しないほうがよさそう。
composition api
目玉機能!
main.tsで@vue/composition-api
をimportする。
import VueCompositionApi from '@vue/composition-api'
Vue.use(VueCompositionApi)
各Vueコンポーネントで使う時
dataやMethodsは、setup関数内でリアクティブにする。
※importは、必要なものを適宜変更する
import {
createComponent,
reactive,
SetupContext
} from '@vue/composition-api'
export default createComponent({
setup() {
// リアクティブデータ、関数を定義していく
const state =reactive({
text: 'text',
price: 1200
}),
const isNumber = (price: number) => {
state.price = price
},
// 最後にreturnで返す
return {
state,
isNumber
}
}
})
propsの定義はtype Props
を定義してsetup関数の引数としてPropsを渡してアノテーションをつける
type Props = {
text: string;
};
export default createComponent({
props: {
text: {
type: String,
default: "default"
}
},
setup(props: Props) {
props.text
}
})
算出プロパティはsetup関数内で、以下のように記述。setup関数内でretrunする。
const priceLength = computed(() => {
return state.price.length
})
感想
- 関数をretrunで返すシンタックスの方が可読性は良さそう
- 今までthisを書いていた箇所は不要になる。
- refなのかリアクティブなのか一瞬わからなくなる
TODO
- 他のVue3.xxで追加される機能についても試す