- はじめに
- 主に2通りのやり方がある
- 想定している読者
- Class Styleの書き方
- Class Styleの特徴
- Object Styleの書き方
- Object Styleの特徴
- どっちで書く?
- まとめ
- 参考
はじめに
こんにちは。フロントエンドチームのayoshです。
この記事では、TypeScriptとVue.jsで開発を行う方法について紹介していきたいと思います。
自分の参加しているプロダクトでもTypeScriptとVue.jsを用いた開発をしていますが、最近のWebアプリケーションのフロントエンド開発ではTypeScriptとReact、もしくはTypeScriptとVue.jsで開発をしている現場は多いのではないでしょうか?
主に2通りのやり方がある
様々な記事でも紹介されていますが、Vue.jsとTypeScriptで開発をする方法は多く分けると2つあると言われています(今回は触れませんが、composition APIも含めて3通りある、という見方もあるようです)。
Vue.extend()
を用いた書き方(いわゆる Object Style)class MyComponent extends Vue
とする書き方(いわゆる Class Style)
書き方にかなりの違いがありそれぞれ特徴があるので、比較をされている記事も結構ありますが、ここ数年で状況が結構流動的だったようなので改めてまとめてみたいと思います。
想定している読者
読み手として下記のような方を想定しています。
- Vue.js + JavaScriptで開発をしたことがある
- TypeScriptはなんとなくわかるが、Vue.jsのプロジェクトに導入したことはない
要するに、
- Vue + JS = 🙆♂️
- Vue + TS = これから
という方( = ちょっと前の自分)です。
ではまずClass Styleから紹介します。
Class Styleの書き方
こちらは名前の通り、コンポーネントをクラスとして宣言します。
Vue.js公式よってメンテナンスされているvue-class-componentに加え、デコレータによってより見易く書けるvue-property-decoratorを使用する書き方で、Vue CLIを用いてvue create
やvue add typescript
した際、Use class-style component syntax?
の質問にyes
とした場合に構成されるのがこのスタイルです。
import { Component, Prop, Vue } from "vue-property-decorator"; interface ComplexMessage { title: string, okMessage: string, cancelMessage: string } @Component({ // conponentsは@Componentデコレータの引数に渡す components: { MyComponent, }, }) export default class HelloWorld extends Vue { // propsはそれぞれ@Propデコレータを使って定義する @Prop() public message: string; @Prop({ required: true }) public complexMessage!: ComplexMessage; // dataはクラスのプロパティとして定義する private name: string = 'Example Name'; private count: number = 0; // computedはクラスのgetterメソッドとして実装する get isZero(): boolean { return this.count === 0; } // methodsはクラスのメソッドとして実装する public outputMessage(): string { return this.message; } // watchは@Watchデコレータの引数にwatchする対象を渡す @Watch('count') public doSomething(c: number) { // ...do something } }
Class Styleの特徴
それぞれのOptionをオブジェクトでまとめて記述する基本のVue.jsの書き方と違って、クラス構文を用いて記述する為、少しスッキリして見えます。よりTypeScriptっぽい書き方という表現もできそうです。
ただ、JavaScript + Vue.jsでの書き方に慣れている方であれば、書き方が大きく変わる事で少し困惑することもあるかもしれません。
その他にも以下のような特徴があげられるようです。
- 利用者が多い
- vue-class-componentは公式にメンテナンスされている
- Vue.js初期からある為資料が豊富
利用者が多く資料が豊富、というのは結構惹かれるポイントです。
では続いてObject Styleを見てみましょう。
Object Styleの書き方
Vue.js公式のTypeScriptのサポートのページでも主に紹介されているのがこのスタイルです。Vue.js + JavaScriptで開発をしたことがある方は見慣れた形ではないでしょうか。
Vue CLIを用いてvue create
やvue add typescript
した際、Use class-style component syntax?
の質問にno
とした場合はこのように記述されています。
import Vue from "vue"; // dataオブジェクトのそれぞれのプロパティの型をまとめて定義し、dataの返り値の型として注釈する export type DataType = { name: string; count: number; } // Object型のpropの型を定義、PropType<>に型引数として渡す interface ComplexMessage { title: string, okMessage: string, cancelMessage: string } export default Vue.extend({ name: "HelloWorld", components: { // JavaScript + Vue.js同様の記述 MyComponent, }, props: { // プリミティブな型は普通に型注釈する message: String, // Objectなどの場合はPropType<>の型引数に定義した型を渡してキャストする complexMessage: { type: Object as PropType<ComplexMessage>, required: true } }, data(): DataType { // dataオブジェクトの返り値を型注釈 return { name: 'Example Name', count: 0, } }, methods: { // それぞれの返り値を型注釈する outputMessage(): string { return this.message; } }, computed: { // それぞれの返り値を型注釈する isZero(): boolean { return this.count === 0; } }, watch: { // 引数・返り値に型注釈する count(c: number): void { // ...do something } } });
Object Styleの特徴
こちらはimport Vue from "vue";
としている事からわかるように、本体に追加されている機能です。
大枠はほとんどJavaScriptの書き方と変わらず、TypeScriptの基本的な型注釈ができればJavaScriptからの移行も容易にできそうです。
一方、それぞれのOptionはオブジェクトとして区切られる為、懸念ごとが区切られてしまうという弱点はJavaScriptでの書き方でのデメリットをそのまま受け継いでいるともいえます。
どっちで書く?
簡単に両方の特徴をまとめてみましたが、どちらで書くのが良いのでしょうか。
見やすさ・馴染みやすさ
これは好みが分かれるところかもしれません。TypeScriptでクラスを積極的に使った書き方に慣れていればClass Styleの書き方はスッキリとしていて見やすいと感じるでしょうし、JavaScriptでVue.jsを書いていた人からするとObject Styleの書き方は馴染みがあって移行もスムーズでしょう。
利用者の多さ
これはClass Styleに軍配が上がっているようです。Vue.jsの初期からあることに加え、v2.5以前のObject Styleではthis
やProps
の型注釈・型推論に難があったこともあり、Class Styleで開発をする人の方が多い様子。利用者が多ければ記事などで情報も見つかり易いといったメリットもあります。
公式のサポート
長く運用するプロジェクトであれば公式のサポートもきになるところです。
利用者の多さで優っていたClass Styleですが、Vue3ではRFCで廃案(Abandoned)となっています(サポートは続けられるとの事)。対してObject StyleはVue本体の機能なので、この面ではメリットになりそうです。
まとめ
Object Styleにあったthis
やprops
の型の問題もあり、一昔前まではClass Style一択の風潮が見られたものの、v2.5でこれらが改善されてからはObject Styleを推す記事もよく見つかります。また、今回は触れなかったVue3系のcomposition APIを使うとObject Styleにある「関心ごとの分離」などの弱点を補える事もあり、情勢の逆転もあり得るかもしれません。
実際にはVue3系の導入や周辺ライブラリなど考慮すべき点はまだまだありますが、この記事では簡単にですがClass StyleとObject Styleの特徴をまとめてきました。
これからVueプロジェクトにTypeScriptを導入しようとしている方の助けになれば幸いです。
参考
- Vue.js TypeScriptのサポート
- Vue 2.5 released
- Upcoming TypeScript Changes in Vue 2.5
- [Abandoned] Class API proposal
- デコレータ使わない Vue.js + TypeScript で進んだ「LINEのお年玉」キャンペーン
- このタイミングで Vue.js に TypeScript を導入するには?
- VueにTypeScriptを導入する3つのやり方を比較してみた
- 最小限の構成でVue.extendとクラスコンポーネントを比べてみる
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com