Rのつく財団入り口

ITエンジニア関連の様々な話題を書いているはずのブログです。

【JavaScript】Vue.jsをサーバサイド風に例えて説明してみる

メタファーを使ってみよう

 様々な言葉が飛び交い、文脈によって意味が違ったりもするIT用語。何かを説明するときに比喩表現を使うことも多いかと思います。かっこよく英語で言うとメタファー(Metaphor)というやつですね。

 僕はアーキテクトっぽい立ち位置にいるので仕事柄、プロジェクトの開発メンバーや新たに加わるメンバー、開発の一線から離れたプロマネの人、技術に疎くなってしまった管理職や偉い人、共同開発の人や顧客など様々な人に、技術的な説明をしたりする機会が時々あります。
 最近はVue.jsのことを説明する機会があり、そういえば相手がわかるようにサーバサイドに例えて話すことが多いなあとふと思いました。ということでこのエントリではその話を書こうと思います。
 だいたい、聞き手は以下のような人であることを想定しています。

僕は専門外なのですがiOS/Androidアプリはおそらく勝手がいろいろ違うと思うので除外です。またサーバサイドがNode.jsの場合もまだ知見がないので除外です。また、「メソッド」と「関数」は言語によって違ったりしますが同じような意味で使っています。
 まあネタなので話半分にご覧ください。ふろんとえんどとかいうナウい技術を追っとる若いモンには悪いが、ワイのとこも図体がデカいけん、まだまだサーバサイドが元気なんじゃゴホゴホ…(突然の老人プレイ)

Vue.jsの基本的な構成、考え方

Vueインスタンス

 JavaScript構文で new Vue({.....}) してJSオブジェクトを生成するので、そのままオブジェクト指向言語のクラスインスタンスのようなもの。コンストラクタ呼び出し時の引数で、いろいろオプションを設定するイメージ。
 単に生成するなら new Vue({.....}) でもいいし、変数に格納するなら const vm = new Vue({.....}) のように書く。変数名はViewModelに倣ってvmを使うのが慣例。変数に入れておくと、所定の書き方を使えば外部のネイティブJSからもVueインスタンス内部(及びまたその中のVueコンポーネント)のデータ、メソッドにアクセスできる。

elプロパティによるマウント

 同名のメソッドもAPIで定義されているが、要はそのid属性を持ったHTMLタグとVueインスタンスが対応づけられ、以降そのタグの中身はVue.js管理下になるよということ。通常 <div> タグが使われる。
 この中身のない空のdivタグが最初は真っ白な無地のキャンパスで、その中にVue.jsがDOM操作の筆を使って自動でいろいろ絵を書いてくれるようなもの。(このへんはAngularやReactでも同じ。)

Vueコンポーネント

 Vueインスタンスをクラスインスタンスに例えるなら、そのメンバ変数として子孫にあたる別のクラスインスタンスを持っているようなもの。Vueコンポーネントは自前でnewして生成する訳ではなくVueインスタンス生成時に連動して自動的に作られるので、オプション類は予め定義済みのイメージ。ロギングしたりすると分かるが、親のVueインスタンスよりコンポーネントの方が先に生成される。
 VueインスタンスとVueコンポーネントの違いは、

iwasiman.hatenablog.com

Vueコンポーネントの親子関係

 あるVueコンポーネント <my-component></my-component>は描画時に中身が展開され、実際のHTMLに書き換わって行く。その時に子に当たる別のVueコンポーネントのカスタムタグがあったらまた中身が展開…と、HTMLの描画的には親子関係というより入れ子関係である。図で示す時は通例に従って上が親、下が子で表されることが多い。
 またこの親子関係は、子は親の性質(メンバ変数、メソッド)を直接受け継ぐということはないので、オブジェクト指向のクラス継承の考え方とはちょっと違う。
 子コンポーネントから親コンポーネントや親インスタンスのデータ、メソッドにアクセスする手段があるので(props down, events up でthis.$emit()で呼び出せる)、Vue.js には厳密なオブジェクト指向の継承にあたるような概念はない。(下のミックスインが一応近い。)

ミックスイン

 Vueコンポーネントと同じような記法でデータとメソッドを書いたJSオブジェクト。これをVueコンポーネントの定義の中で使うよう書くと、そのミックスインの中のデータとメソッドが使えるようになる。機能が取り込んで混ざるイメージ。PHP言語のtrait、Ruby言語のmixinとだいたい同じ。Pythonにも似たような機能がある。
 ミックスインのことは公式ガイドの中では後半に書いてある。Vueコンポーネントをたくさん作るような大規模開発でないとたぶん使わないと思われるので、Vue.jsを初めて学ぶ人はとりあえず後回しでよい。

Vueコンポーネントを表すカスタムタグに渡すパラメータ

 上でVueコンポーネントのオプション類は予め定義済みのイメージと書いたが、Vueコンポーネントをクラスインスタンスに例えると、インスタンスを生成する時のコンストラクタ引数でメンバ変数にデータをセットするようなもの。

<blog-post title="Vue.jsを学ぼう" v-bind:postDate="varDate"></blog-post>

 のようにすると、blog-post コンポーネント(≒BlogPostクラスのインスタンスとか)が中で持っているメンバ変数のtitleとpostDateに値が入る感じ。JavaScript動的言語なので、文字列、数値、配列、真偽値、オブジェクト、なんでも渡せる。
 また上の例のv-bind:のようにバインディングが効いた状態で変数を渡すと、外側でその変数の中身を変えればVueコンポーネント側でも反映される。これは参照渡しやポインタのイメージ。

そもそもコンポーネントとは

 画面全体であったり、テキストボックス検索窓+結果一覧の組であったり、ラジオボタン一組であったり、単位は自由。HTML的にはある開始タグから閉じタグまでをひとつのカスタムタグに閉じ込め、中身をVue.js側にお任せしたもの。
 元来サーバサイドではモデル2MVCやMVPなどの各種アーキテクチャ・パターン、関連してドメイン駆動開発(DDD)やClean Architectureの考え方などなど、クラスの責務を厳密に定義して配置場所のレイヤーごとにきちんと分離して整理したり、設計の見通しを良くするための工夫がいろいろされてきた。
 クライアントサイドJavaScriptでも同じような試みはされてきたが(初期のフレームワーク Backbone.jsなど)、画面と強く結びついている分あまり綺麗にはいかなかったらしく、レイヤーで分けるアーキテクチャでなくコンポーネント指向が主流になっている。  あるカスタムタグ内のHTML的な描画、データの保持、ロジック処理、イベント処理、サーバとの送受信…などひっくるめて諸々が全部「コンポーネント」という単位のかたまりの中に詰め込んであり、外側からはそれらのコンポーネントを組み合わせてHTMLで画面を作っていけるイメージ。
 この、コンポーネントの中の処理が隠蔽されて外側からは気にしなくてよいという点は、オブジェクト指向のクラスと似ているとも言える。同じコンポーネントを複数使うとそれぞれは別々のインスタンスになり、中身は別なところもクラスの考え方と同じ。

Vueインスタンス/コンポーネントのライフサイクル

 beforeCreate, created, beforeMount, mounted...と生成されてから消滅されるまでのライフサイクルがいくつか設定してあり、同名のプロパティとして関数を定義しておくと、自動的に呼んでくれる。実際にコンポーネントを作ってconsole.logでログを仕込んで動かすとすぐイメージが湧く。createdでサーバーと通信などロジック記述可能、mountedでDOM要素にアクセス可能と覚えておくとよい。
 例えが古いが、JavaフレームワークJavaServer Faces(JSF)はリクエストが来てからレスポンスが返るまでにライフサイクルとして6つのフェーズがある。ASP.NETにおけるWebページにもライフサイクルがあり、イベントが10個ぐらいある。これらと同じようなもの。

単一ファイルコンポーネント(Single File Component, SFC)

 拡張子 .vue のひとつのファイルの中に、HTMLの見た目部分、Vueコンポーネントの処理の部分、CSSの定義部分を書いたもの。単一ファイルコンポーネント同士は互いに完全に独立しており扱いやすい。本格的なVue.jsアプリケーションを作るならほぼ必須になる。
 サーバサイドのモデル2MVCアーキテクチャに基づいたフレームワークで喩えると、ある画面の実現に関わるModel層、Controller層、View層のクラスやファイルや部品などなどが全部ひとまとまりになったようなもの。レイヤーごとでなく画面ごとにまとめていく。そしてまとめる単位が1画面全体だと大きすぎるので、もう少し小さく…ヘッダ部分でひとつ、パンくず表示でひとつ、検索条件+結果一覧でひとつ…のようにしていったものが、単一ファイルコンポーネントのイメージ。
 ちなみにここではModel層と例えたが、クライアントサイドのブラウザ上で動くJavaScriptフレームワークはどこか別の場所にあるDBに直接アクセスできるわけではないので、そこはサーバとの通信を介してアクセスすることになる。JSではお手軽なJSONフォーマットが標準。

HTML部分の書き方

データバインディングで使うマスタッシュ構文

 サーバサイドのフレームワーク各種のView層に相当する技術で、コード上に定義された変数や画面と紐付いたクラスインスタンスの中身など、動的な値をHTML部分に出力する書き方は各種用意されている。

<%= thisIsJavaJSPVar %>
<%=thisIsCSharpASPNETVar %>
<%= @this_is_ruby_rails_var %>
{$this_is_PHP_Smarty_template_var}
{{$this_is_PHP_Laravel_Blade_template_var}}
{{ this_is_Python_Django_var }}

 これらとまったく同じような感じ。
 なお上の例でもPHPのLaravelフレームワークPythonDjangoフレームワークでは変数の出力が {{ }} 囲いと、マスタッシュ構文と被っている。場合によっては表示エラーの原因になる。これらはFW側で解決方法が用意されていることが多い。(Laravelでは@{{ }} と最初に@をつければ解決)
 また、あまり使われているところを見ないが実はVue.js側でも、Vueインスタンスで delimiters プロパティを指定すればデリミタ記号を {{ }} 以外に変えられる。(Vue.js 2.*系 の場合。)

タグの属性にディレクティブを書いて制御する
  <li v-for="value in valuesArray">
    {{ value }}
  </li>

のように、Vue.jsを使っていると既存のHTMLタグの属性として、v-forとかv-ifとかv-showとかv−*で始まる見慣れないカスタム属性がたくさん出てくる。
 サーバーサイドのフレームワーク各種でも、View層に当たるクラス/ファイルで条件分岐や繰り返しなどの制御構造を書けるようにする仕組みは各種用意されている。上の例では配列の数だけ<li></li>タグが繰り返し展開されるが、サーバサイドの仕組みだとこのような感じ

<% @member_names_from_rails.each do |member_name| %>
  <li><%= member_name %></li>
<% end %>

やることは同じだが、違うのは実行されるタイミング。

サーバサイドの仕組み:
応答のHTTPレスポンスのボディの文字列を生成する処理(View層やController層)で実行され、上のような繰り返し処理なら中身が展開され、展開された状態でHTTPレスポンスで返ってくる。レスポンスが渡ってくるとブラウザが単にそれを読み込んで画面として描画し、ユーザーに見せる。

Vue.jsのようなクライアントサイドの仕組み:
サーバサイドの処理でのHTTPレスポンス生成の段階では、HTMLの中やJavaScriptの中に書かれたVue.jsの繰り返しの指定は展開されない状態でHTTPレスポンスでクライアント側に返ってくる。それをブラウザが読み込み、さらにVue.js本体のコードと画面のJS実装のコードも読み込み、ブラウザ上でロードが終わるとVue.jsが動き出してDOM操作を始めて中身を展開し、ユーザーに見せる。ユーザ体験にあまり差はないが処理順序でいうと、展開がワンステップ遅れるような感じ。

ディレクティブを自作する

 実は可能で、Vueコンポーネント的に書いて、それを使うコンポーネント専用に登録したり全体に登録したりできる。
これはサーバサイドのフレームワーク群で、カスタムタグをクラスの形で定義したりするのとまったく同じイメージ。

v-onディレクティブのイベント記述

 旧来のJavaScriptだとボタンのHTMLタグに onClick="javascript:clickSearch()"をつけたり、Visual StudioVBC#のアプリを開発していたらボタンのダブルクリックで開くコードビハインドのクラスにイベント処理を書いたりしたアレと同じ。onclickでなくclickだったり旧来のJavaScriptのイベント名と若干違う時があるのに注意。イベント修飾子各種やキー修飾子のエイリアスが揃っていたり、実装を楽にするように工夫されている。

Vueコンポーネントの中身の書き方

{ }入れ子やインデントが多かったりして最初は戸惑うコンポーネントの書き方。混乱してきたら基本に返ると良いです。

  • Vueコンポーネントも実体はJavaScriptオブジェクトであり、連想配列である。
  • 連想配列は「キー:値」でなんでも入るデータの入れ物で、値には配列もOK。配列の中のひとつひとつはカンマで区切る。
  • そしてJavaScriptにおいては関数も第一級オブジェクトなので、配列の中のひとつひとつの変数に関数も代入できる

…と積み上げていくと、methodsプロパティ配下のメソッド群にカンマ区切りが必要なのがハラオチします。僕も最初はこのへんが分かりませんでした。
 ふつうオブジェクト指向言語ではクラス定義でメソッドとメソッドの間の区切りは改行か空行1行なので、他言語経験者だとこのメソッド間のカンマ忘れは割とやりがちな気がします。僕もよくやらかしました…トランスパイル時にいつも教えてくれてありがとうwebpack...😂

propsプロパティ (プロパティをオプションとも呼ぶ)

 Vueコンポーネントを示すカスタムタグのパラメータで指定した値が自動的に入る、読み出し専用のデータの入れ物。dataプロパティと全く同じように this. でアクセスできるが、propsは後から更新してはいけないとされている。
 オブジェクト指向のクラスのインスタンス生成時、コンストラクタの引数で指定した値が自動的に入る、リードオンリーなメンバ変数のようなもの。

dataプロパティ

 そのまんま、クラスインスタンスのメンバ変数のイメージ。private/protected/publicのようなスコープに相当するものがないので、基本publicである。Vueコンポーネント内で初期値を設定し、値を後から変えないようにすれば、一応 const や static な雰囲気にはできる。
 このdataプロパティの値を変えると結びついたHTMLのタグ内の値も自動的に変わる、逆に画面側でテキストボックス等で値を変えるとdataプロパティも自動的に変わる、というのがVue.js の双方向データバインディングの強み。Chrome拡張のVue.js devtoolsなどでdataを見ながら画面を動かすと雰囲気がよく分かる。
 見た目の処理とJS上のロジック処理を切り離し、データに対してのみプログラミングすることでアプリケーションを作っていける。

computedプロパティ

 HTML指定部分ではdataプロパティ配下の値と同じように、someComputedData() でなく someComputedData と最後のカッコなし変数名で書く、値を表示用に加工する仕組み。dataプロパティ配下の値のように見えるが、実体は引数なしのメソッドで、dataプロパティ配下の金額の値に3桁カンマ区切りを追加など、ちょっとした加工を行う時に使う。computedなメソッドから他のcomputedなメソッドは呼べないが、methods配下のメソッドは呼べる。値はキャッシュされる。

別解:computedプロパティはdataプロパティ配下の値と対応させ、setteter/getterを定義することもできる。オブジェクト指向のクラスにおける、あるメンバ変数に対するgetter/setterメソッドの組で、getterは対応するメンバ変数の値をただ返すのでなくちょいと加工してから返すようにしたような感じ、という理解の仕方でもよい。

methodsプロパティ

 そのまま、クラスのメンバメソッド群。private/protected/publicのようなスコープに相当するものはない。あるメソッドから別のメソッドを呼んだり、内部メソッド的なものを作ったり、JavaScriptでできることは可能なのでサーバサイドでのクラス実装と大差ない。

watchプロパティ

 dataプロパティのある値を指定すると監視対象になり、変更があったらこの処理を行う、このメソッドを呼んでイベント処理…などの変更検知が簡単にできる仕組み。プレーンなJavaScriptでテキストボックスに onChange="javascript:doSomething()" を仕込むようなもの。
サーバサイドの仕組みだとよくバッチ処理で特定のフォルダにファイルが置かれないか定期的に監視する…などのアレみたいなものだが、自動的に監視してくれるので見に行く時間をcronで定義したりする話とはちょっと違う。  

filterプロパティ

 入力値に加工処理を施して出力する…というメソッドを定義したもの。computedプロパティでも同じようなことができる。Unix/Linuxコマンドでのテキストフィルタ処理みたいなもの。実装上の書き方もUnix思想に習って、パイプ記号の縦線で書く。

<!-- mustaches -->
{{ message | capitalize }}

関連ライブラリ

Vue Router

 サーバサイドのフレームワーク各種では、

  • GET/POSTでURLを持ってリクエストが飛んでくるので、パスの文字列を解析して取得
  • Controller層的なレイヤーで対応するクラスの対応するメソッドを呼んでサーバサイドの処理開始
  • 上記の対応づけをを自動で紐づけたり、設定ファイル的な仕組みで対応関係を持ったりして実現する

ということをしている。これをURLルーティングの機能と呼ぶ。まったく同じことをクライアントサイドでJavaScriptを使ってやっているもの。
 Vue RouterはほぼSPA向けなので、対応する画面用のクラスでなく対応するVueコンポーネントが呼ばれる。URLのパラメータ各種を読み取ってコンポーネントに渡せたりするところもサーバサイドの仕組みと同じ。

Vuex

 親子関係にあるVueコンポーネントがいくつも入り乱れてきたりする複雑な画面で威力を発揮する、状態・データ管理のライブラリ。
 サーバサイド的に例えて言うと、

  • GoFデザインパターンのSingletonパターンを使ってデータ管理クラスを作成
  • その中にメンバ変数として状態やデータをカプセル化して保持、持つのはメモリ上
  • 外側からのアクセスは必ず所定のgetter/setterメソッド経由を強制するようにする
  • 以上のようなクラスで実現した、どのレイヤーからでもアクセスできる簡易的なデータベース/キャッシュ/共通データの置き場…のような仕組み

を連想すると近い。この例えだとサーバサイドでアプリケーション全体で常にひとつになるが、JavaScriptはクライアント上で動くので、Vuexのデータ置き場は端末でユーザが開いている画面ごと(=SPAならアプリケーションごと)にひとつになる。一応1画面に2つ以上作ることもできる。

※最近のブログ記事でこれに関連して興味深く拝見したのが、技術書典の「このすみ堂」でお馴染みのこのすみさん(id:konosumi)の以下の記事。

www.konosumi.net

フレームワークがVue.jsでなくてReactですが、Reactでよく使われる状態管理のライブラリReduxについても同じように、Redux => データベース、呼ぶためのActionなど所定のコード=> SQL と置き換えると分かりやすいよ、という話をされています。やっぱり似たような理解になるんですね。このへん、フロントエンドの技術は関連しあっていて面白いですね。
 ちなみにこのすみ堂さんの本は『Firebase + React.js リアルタイムアプリケーション入門』を読んだのですが、Firebaseの実物のイメージが湧いて分かりやすかったです。 konosumi.booth.pm

フロントエンドの技術全般

npmによるライブラリ管理

 昔はJavaならライブラリのjarファイルを一生懸命インターネットから探してダウンロードしたり、C#ならライブラリのdllファイルを一生懸命探して配ったり、手動で管理していた。これが今ではオープンソースのライブラリ類は最初から公式でGitHubなど所定の場所にアップロードする決まりになっており、ライブラリ管理の仕組みを使うとコマンドでインターネット上からダウンロードして使えるように便利に進化している。依存関係の解消などもしてくれる。JavaScript開発におけるライブラリ管理は、このnpmが標準。(厳密にはyarnなど他もある。)
 C#ならNuGet、PHPならComposer、RubyならRubyGemsPythonならpip等、Scalaならsbaz、Go言語ならdepやglide、Swiftでも各種……とモダンなプログラミング言語の環境では大体ライブラリ管理の手段が用意されている。Javaだとビルドツールがライブラリ管理も含む形になり若干形態が違うが、MavenやGradleが相当。

Babel、babel-polyfill等を使ったトランスコンパイル、略してトランスパイル

 あるプログラミング言語の新しいバージョン特有の書き方を、古いバージョンでも動くように自動的に変換してくれる仕組みのJavaScript版。公式サイトのREPLのページで実際に変換される様子を見るのが分かりやすい。 babeljs.io

JavaだったらJava8から話題になったラムダ式の短いコードを、伝統的なふつうのコードに自動で変えてくれる仕組みのようなもの。

※ちなみにワタクシはいまいち使い所がなくてラムダ式使ってません。HAHAHA😇

webpackを使ってのバンドル諸々

 たくさんあるjsファイルの中のコードをひとかたまり(もしくは複数)にまとめ、この時に依存関係も解決し、上のBabelのような変換の仕組みも一緒に行ってくれる仕組み。この一連の操作をバンドルという。他にもツールはあるし過去流行ったものもあるが、日本だとモジュールバンドラーツールとして事実上このwebpackが主流。
 バンドルされたファイルの中身は、名前空間が加わったり関数の名前が変わったり、Babelが変換してくれていたり、改行が消えたりコメントが消えたり行頭にコメントがついたり、難読化されて人間の目にはもはや読めなくなっている。あくまでテキスト形式のJSコードだが、雰囲気としてはバイナリ形式の実行可能ファイルにも近い。
 …と連想していくと、Javaの伝統的なAnt/Maven/Gradle/その後はSBT/Bazelなどのビルドツールを使ったビルドに、非常に近いイメージになる。
ちなみにコード変換の用語の定義としては以下。

  • コンパイル:人間が読める形式のコード(テキスト)→機械が読める形式(バイナリ) なのでC,C++,C#,VB,Java,Kotlin,Scala,Goなどはこちら。
  • トランスコンパイル:あるプログラム言語のコード(テキスト)→別の言語の同等のコード(テキスト) なのでフロントエンドのJavaScript変換はこちら。
  • ビルド:コンパイル以外にライブラリのリンクや関連するファイルを一式集めて、アプリケーション全体が実行可能な形態にまとめること。コンパイルの動作がない言語でも同じような意味で使う。

モダンなJS開発ではいろんなライブラリや仕組みを駆使して、言語にTypeScriptを使ったりCSSの進化した技術を使ったり果てはCSS自体や画像も含めたりして、webpackで最後にまとめてアプリケーションを作っている。なので実質「トランスコンパイル」≒従来の「ビルド」と同じ意味で使うことも多い。npmのコマンド類でも build の単語はよく出てくる。他言語での一般的なビルドと同じようなイメージで良い。

おわりに

 中にはサーバサイドがほとんど関係ない話や余談も混じってしまいましたが、こんな感じでした。

 僕も今年2018年からフロントエンドに触り始めて基礎は分かった(つもり)ですが、学んでいて面白かったのは上で最後にあげたwebpack回りですね。今20代ぐらいの方で、最初に触れた技術がフロントエンドだったりするともうまったく知らない場合もあるのでしょうか、2000年代~大企業だと今でも、規模大き目めの開発をしっかり支えてきたJavaでは上のようなビルドツールを使います。
Javaのコードをコンパイルした後の.classファイルやライブラリ類の.jarファイル、.xmlなどの設定ファイル、変換をかけた設定ファイル、画像、CSS、外部JSコード、諸々全部、コマンド一発のビルドで固めて.war形式のWebアーカイブファイル(実体はZIP形式のファイル)を作り、サーバーにデプロイ(配置)してめでたくアプリケーションが動き始めます。
 フロントエンドの技術で言うと、オプションでいろんな処理を含められて最後に全部一式まとめるwebpackの仕事がまさにこれに近いんですね。そうか最先端の主戦場はクライアント側、ブラウザの上に移り、メインウェポンがかつては脆弱だったJavaScriptに変わっても歴史は繰り返すのか……いや進化してるのだから、テスト駆動開発で有名な[twitter:@t_wada]さんのスライドにあるように螺旋になるのか……?としばし感慨に耽ったりしました。

 Webpackでトランスコンパイル回りでどんなことができるのかは、電子書籍オンリーですがこの『速習webpack』に詳しくまとめられていてお勧めです。CSSや画像も一緒にバンドルできちゃうんですね。  

速習webpack 速習シリーズ

速習webpack 速習シリーズ

Vue.jsでTypeScriptを使う

 Vue.jsでも実は使えるAltJS言語TypeScript。まだVueでやるのはつらみが多いと前にどこかで聞いたのですが、コマンドから新規プロジェクトを作ったりできるボイラープレートのツール、Vue CLI(vue-cliとも)のバージョン3.0がリリースされ、より身近に使えるようになったそうです。以下の記事の対比がとても分かりやすかったです。

https://mae.chab.in/archives/60167

表にまとめると以下のようになります。

オブジェクト指向言語の概念 Vue.js Vue.js+TypeScript
クラス Vueコンポーネント、実体はJSオブジェクト TypeScriptのクラス
継承 ない extendsで実現
メンバ変数
(プロパティ)
dataプロパティ配下全体を関数の戻り値にし、中に配列で並べる 明確にクラスのプロパティ、関数不要
メソッド methodsプロパティ配下の関数の配列 明確にクラスのメソッド
Vue.jsの概念 Vue.js+TypeScript
computedプロパティ get/setアクセサで実現
props down, events up @Props、@Emitデコレーターで実現
ライフサイクルの関数 そのままクラスメソッド
watchプロパティ @Watchデコレーターで実現
filtersプロパティ @Componentデコレーターで実現

 本エントリで書いたこともだいたい、「Vueインスタンス/コンポーネント≒他言語のクラス のメタファーで考えるといいよ」という話なんですが、TypeScriptを使うとより明確にクラスになるわけですね。これは分かりやすそうです。そして上記記事でもセルフツッコミ的にありますが、TypeScriptで書くとAngularとどんどん似てくるというのが面白い。究極的にはみんな一緒になっちゃったりするんでしょうか。

そしてTwitterでも話題になっていましたが、Vue.jsのがっつりした本格解説本が2018/9/22に出ます。コミッターやコミュニティの方々が結集、豪華執筆陣によるかなりの意欲作とのことでこちらも期待です。