*この記事は2020年3月頭に書かれている記事です
どうも、Vueはいいぞおねーさん(自称)です。
Vue.jsは私に言わせるととてもよいフロントエンドフレームワークであり、その理由の一つにプログレッシブフレームワークである(段階的に利用する機能を増やしていくスタイルにマッチしている)ものとして、フロントエンド初学者の皆さんにもおすすめしたい代物です。
しかし、現在までに様々なプラクティスが考案されたがゆえに、「最初からベストな方法で始めたい」という思いから一度にたくさんのことに挑戦してしまいたくなりがちです。
そしてそれはプログレッシブという思想に反するもので、結果として挫折を生んでしまっているのではないかと思いました。
そこで今回は「知るのを後回ししてよいこと」として、Vue.jsへの入門する方へのアドバイスを独断と偏見で不要度という指標でまとめてみました。
不要度というネガティブな指標なのは、それ以外は入門でも目を通しておいたほうが捗るぞという意味です。優先度だと網羅しなければいけない項目があまりにも増えてしまうので……
真っ先に目を通すべきは テンプレートのマスタッシュ記法 {{ hoge }}
、ディレクティブ(v-if, v-for,v-bind, v-on, v-model)
、スクリプトのdata
, methods
, computed
, watch
あたりでしょう。
独断と偏見なので、マサカリ歓迎です。
-- 3/7 13:00頃加筆 --
この文書が目指すレベル感は「今からVueを始める人」「始めたけど情報量が多くて混乱してしまった人」が「入門期の混乱を脱出する」です。
入門レベルを抜けてVue.jsに慣れてきたり、プロダクションレベルやチーム開発のレベルでは「後回しにしたこと」を改めて学び直すと良い発見があったり、周囲が当たり前のように使っている機能がわかるようになるでしょう。
(だいたい不要度:★★★くらいまでは小規模なチーム開発でもよく使われるのではないかと思います)
#ライブラリ選定
Vuex 不要度:★★★★
Vueのデータ管理の方法として、基本セットのように語られがちなVuexですが、本当に必要なものなのかどうかよく検討しましょう。Vuexを利用しようとすることで必要になる知識はかなり多いように思います。
ではVuexが必要かどうか検討するとはどのようなことでしょうか?
これは、基本的にシングルページアプリケーション(SPA)においてページ間でデータを保持し続けたい場合のみと考えてよいと思います。
SPAになっていなければ、つまりサーバーサイドで別々のページになっている場合も基本的には不要です。
Vueはコンポーネントが別れている場合、親→子へのデータの受け渡しは非常に簡単、子→親へのデータの受け渡しはやや難しい一方で、兄弟にあたるコンポーネント間のデータのやり取りは基本的にできません。
だからといってVuexを導入するのは学習コストが高すぎるのではないかというのが持論です。
その場合、一番親にあたるコンポーネントまでデータをさかのぼってバケツリレーするのが基本です。
邪道ですが親から子へオブジェクトをpropsとして渡すことで子の変更を親が感知することができます
Vue Router 不要度: ★★
あなたのプロジェクトはシングルページアプリケーション(SPA)ですか?
つまりページ遷移するかのようにデータを入れ替えたり、コンポーネントを切り替えるかということです。
このライブラリを使うことによって、あたかも実際にページ遷移するかのようにURLを書き換える機能を提供してくれます。
使い方は比較的簡単なので、必要ならプロジェクトに採用しても問題ありません。
できればその前に「Vueのすごさ」として基本的なシンタックスを一通り体験してほしいと思いますが、その上で導入する価値は十分にあるでしょう。
UIフレームワーク・UIコンポーネント 不要度: ★
Element UI、Vuetifyなどのことです。
これらはよく使うWebデザイン上のパーツをコンポーネントとしてまとめたもので、デザインの悩みからあなたを解放してくれます!
それは、プロジェクトの本質に悩む時間を増やしてくれるでしょう。
プロジェクトに導入するためにいくつかの設定やコンポーネントの利用方法を追加で学ぶ必要があるため、Vueそのものにまだ全く触れていない場合はまだ時期尚早かもしれません。
しかし、一通り主要なVueな機能を触ってみた上でなら導入する価値は十分にあると言えそうです。
Nuxt.js 不要度:★★★
Vue.jsと併せて語られることが多いのがNuxt.jsですね!
Nuxt.jsはVue.jsをコアとしていくつかのライブラリを統合したフレームワークです。
とにかく色々な機能が増えていて、そのために設定項目が多岐に渡ります。
主要なところでいうと、サーバーサイドレンダリング(SSR)と併せて追加されるライフサイクル、静的サイトジェネレーター(SSG)、規約ベースに拡張されたVue Router, Vuexなどでしょうか。
果たして入門者はNuxt.jsから始めるべきでしょうか?私はそうは思いません。
VuexとVue Routerを高度に統合しており、プロジェクトの作成に取り掛かりさえすれば豊富な機能が使える一方で、設定項目が多岐に渡るのが難点です。
特に、プロジェクトの種類がSSRを行うUniversalモードと行わないSPAモードが有り、それに加えてSSGでもプロジェクトをサービス運営することができ、最適な方法を選ぶのは難しいのではないでしょうか?
また、機能が増えるということは、Vueの機能なのかNuxtの機能なのか判別が付かず、目的のドキュメントを探すのを困難にするという側面もあります。
ということで、入門者が「Vueって面白いじゃん!」というところまでの助走をつける妨げになるという点でオススメしません。
一方で、一度Vueに慣れた上で本格的なプロジェクトを作ろうと決意したときにじっくりと腰を据えて挑戦するにはよいフレームワークであるとも言えます。
TypeScript 不要度:★★★★
型は好きですか?
動的型付け言語なんて信じられない!型がないと死んでしまう!という人までは止めませんが、
基本的には設定が増えたり型ファイルの生成やその扱い方を知る必要があるため大変になるでしょう。
特にVueにおけるTypeScriptは型の付け方がClass StyleとVue.extendと2つの方法(に加えてVue 3.xからはコンポジションAPI)があり、検索もし辛く、それらの見分けを自分でつけられるようにならなければいけません。
ESLint 不要度:★★
触ってみてイラッ☆としたらはずしちゃってもいいかも。
逆にあってよかったーって思う人はそのままどうぞ。
一方でコードフォーマッタであるPrettierは非常に便利です。
こちらも余裕があれば入れたいです。
StoryBook 不要度:★★★
コンポーネントの一覧をストーリーとして一覧できます。
が、設定がめんどくさいのではじめはなくていいんじゃないでしょうか。
チーム開発、特にデザイナーさんと協業するケースにおいてStorybookは活躍します。
個人でコンポーネントの振る舞いを把握していれば十分なケースでは不要でしょう。
また、後述しますが画像回帰テスト(ビジュアルリグレッションテスト)を行うときにはStorybookを使います。
テスト 不要度:★★★
とりあえずプロジェクトを動く状態に持っていく!という観点ではとりあえず気にしないでいいでしょう。
長く継続していくにあたってはテストは重要な役割を果たします。
どこかのタイミングで導入したほうがよいものではあると言えそうです。
テストに関する補足
Unitテスト(単体テスト)
Jestとか使います
Vueの単体テストはとてもむずかしいです。
Vuexのようなストアや、副作用のないdataの変遷とメソッドのテストは比較的容易に行える上にそれによって守れる部分が多いので大きな見返りがありますが、
イベントハンドリングやレンダリングされるVirtual DOMのテストは作るのが大変な上に壊れやすい上、副作用に悩まされたりブラウザによる差異はわからないなどこの辺りはE2Eテストでカバーする範囲かもしれませんが(以下恨み言が延々と続く)
###E2Eテスト
Puppeteerとか使います?
画像回帰テスト(ビジュアルリグレッションテスト)
reg-suitとか使います。おそらくStorybookが必要でしょう。
画像回帰テストは最初に準備するのが非常に大変ですが、機能しはじめれば意図しないデザインの変更を即座に発見でき、修正や拡張も比較的容易なので個人的にはオススメです
構文解析
vti(Vetur Terminal Interface)というパッケージが最近公開されました。
構文解析を行って、存在しない変数の参照などを検査できるようです。
是非試してみたいです。
プロジェクト設計
Atomic デザイン 不要度:★★★★
コンポーネント分割ができる!じゃあプロジェクトの設計どうしよう?という話で
Atomicデザインを採用しました!という話は非常にたくさん出てきます。
それで、採用した結果はどうだったのでしょうか? 私が一度触ってみた限りではなんかいま一歩足りない気がしました。
デザインと機能面での分割粒度の話が非常に似通っているため一緒くたにされがちですが、
個人的にはうまくワークさせるのが非常に難しいツールなので、
純粋にフロントエンドの設計プラクティスとしては採用しても微妙だなと感じました。
デザイナーさんなどのその他の業種の人と共通言語として語りたい時に効果を発揮する設計指針なので、
その辺りを理解した上で採用するのはありかもしれません。
補足:じゃあコンポーネントの分け方って何を指針に決めるの?
分割したくなった時が分け時じゃないでしょうか(雑
また、スタイルガイド — Vue.js から密結合コンポーネントの名前の項目を参考にするのが個人的には推しです。
Atomicデザインが流行ったけどいまいちワークしきってないと思う割に、その代替になるような決定版みたいなものは私は把握していません。
Vueの機能
コンポーネント分割 不要度: ★
さて、Vueといえばシングルファイルコンポーネント(SFC)を使った開発です。
DRYや構造化は好きですか?
そうですね!適切にコードを分割することは、コードの読みやすさに直結します。
つまりコンポーネント分割したい!
気持ちはわかりますが、いきなりコンポーネントの分割の仕方を考えるのは時期尚早かもしれません。
その前に、データバインディングやv-if, v-forといったテンプレートシンタックス、method、computed、watchなどのscript機能を一通り試してみましょう。
そして、コンポーネントを分割せずにまず一度ページを”完成”させましょう!
動く状態のものを作ったら、一度Gitにコミットするなどして、いつでも元に戻せる状態にしておくことが重要です。
コンポーネント分割は、コンポーネントのマウント、propsによるデータの受け渡し、emitによるデータの巻き上げなど更に多くの知識が必要となります。
一旦は置いておいて愚直に1つのコンポーネントに書き下すことが、Vueの魅力を体験する一助になると思います。
一度動くのを確認してからコンポーネント分割にとりかかりましょう!
(Vue 3.x)コンポジションAPI 不要度:★★★★
Vue 3.xから導入される機能です。
(Vue2.xでもライブラリを導入することで体験することができます)
複数の機能が絡まって複雑化したコンポーネントを用途ごとに整理するのに役立つ他、TypeScriptでの型の取り扱いが更にやりやすくなりますが、 初心者にとってかえって分かりにくくなる ともRFC(提案書)にも言及されています。
従来のオブジェクトスタイルの記法はVue 3.xでも引き続き使えますし、こちらのほうが最初触れるときは分かりやすいでしょう。
Vueの公式ドキュメントに勝手に不要度を付ける
ライフサイクル 不要度:★
mounted以外の beforeCreated, created, beforeMount, beforeUpdated, updated, beforeDestroyed, destroyedのライフサイクルは取り急ぎ忘れてよいのではないでしょうか?
いくつかのエッジケースにおいて「そういえばこんなのないかな」 と探して見つける程度で十分でしょう
一方で、mounted は「初回にAPIをコールする」などの初回に○○したいといったケースで比較的お世話になることでしょう。
テンプレート構文
動的引数 不要度:★★★★★
忘れましょう。
修飾子 不要度:★★
あんまり使わないと思いますが、気になった時にざっと眺めてみると表現力に幅が広がるかもしれません。
算出プロパティとウォッチャ
算出 Setter 関数 不要度:★★★★
算出Setterはあまりユースケースが思い浮かばなかったのでこの不要度にしました。
v-modelをネストするときなんかは便利だそうです。 thanks @Masaki@Web技術者さん - Twitter
僕はv-modelをネストする時に使ってます。
methodsでも十分ですが、副作用ないならこちらも分かりやすくて良いですよ。
_value: {
get(){
return this.value
},
set(value){
this.$emit('input', value)
}
}
クラスとスタイルのバインディング
オブジェクト構文 不要度:★★★
必要になったらどちらかといえばこちらを覚えましょう。
とりあえず一旦不要だと思います。
配列構文 不要度:★★★★
必要になったらオブジェクト構文だけ覚えておけばいいんじゃないかな
インラインスタイルのバインディング 不要度:★★★
CSSならクラスでスタイルしたほうがよいでしょう。
widthとhightの組み合わせやtop, leftなどの座標系の組み合わせをリアルタイムで変化させたい場合に使うくらいでしょうか。
そういう用途がなければとりあえず忘れていいと思います。
条件付きレンダリング
key
による再利用可能な要素の制御 不要度:★★★★
一旦忘れてていいと思います。
デモは触っておきましょう。
リストレンダリング
範囲付き v-for 不要度:★★★★
覚えてなくても困らないと思います。
イベントハンドリング
キーコード 不要度:★★★
###システム修飾子キー 不要度:★★★★
###.exact 修飾子 不要度:★★★★
###マウスボタンの修飾子 不要度:★★★★
使わんのちゃう?
コンポーネントの基本
コンポーネントの編成 不要度:★★
シングルファイルコンポーネント(SFC)ではVue.component()を都度都度ごにょごにょする必要はありません。
スロットによるコンテンツの配信 不要度:★★★
多くのユースケースの場合、propsで渡してマスタッシュ展開またはv-htmlで事足りるのではないかと思うのでこの不要度に設定しました。
コンポーネントの中間に埋め込む要素がHTMLやコンポーネントをまるごと内包できるという点で便利なので、それらが必要になったときはドキュメントを熟読しましょう。
スコープの扱いが慣れないとちょっと不思議な感覚かもしれません。
動的なコンポーネント 不要度:★★★
<component :is="component_name">
あるいは <component :is="tag_name">
という記載方法です。
忘れた頃に思い出して便利だったりしますが、取り急ぎ不要でしょう。
DOM テンプレートパース時の警告 不要度:★★
上述の動的なコンポーネントの記載方法で解決することができます。
問題にぶつかったときは思い出してみましょう。
コンポーネントの登録
コンポーネントの名前 不要度:★★★
シングルファイルコンポーネント(SFC)ではこの登録方法は不要です。
グローバルなコンポーネントの登録 不要度:★★★
コンポーネントライブラリの使う側として呼び出すことはありますが、自分で登録する必要はないでしょう。
ローカル登録 不要度:★
コンポーネント分割をした時によくお世話になるのはローカル登録だと思います。
が、Vueの公式ドキュメントはシングルファイルコンポーネント(SFC)を前提とした書き方になっていないため、
このドキュメントを頼りにしないほうがわかりやすいかもしれません。
基底コンポーネントの自動グローバル登録 不要度:★★★
使わんのちゃう?
プロパティ
プロパティの型 不要度:★
コンソール中に警告が出るだけなので、あってもいいですがなくてもいいと思います。
一瞬nullが渡されたときに挙動が変みたいな時にはあると捗るかもしれません。
プロパティのバリデーション 不要度:★★
コンソール中に警告が出るだけなので取り急ぎ必要ないと思います。
あってもいいですけどね。
プロパティでない属性 不要度:★★★
なんかいい感じにやってくれてるんだなと思えばよいです。
属性の継承の無効化 不要度:★★★★
忘れた頃に変なプロパティの継承がされたら思い出してください。
それまで気にしなくていいです。
カスタムイベント 不要度:★
名前から想像し辛いかもしれませんが、子コンポーネントからデータの巻き上げが必要になったときに使ってください。
.sync 修飾子 不要度:★★★
あえて使うこともあんまりないと思う
スロット 不要度:★★★
コンポーネントの基本で前述しましたので改めて記載しません。
動的 & 非同期コンポーネント及びそれ以降 不要度:★★★★
とりあえず読まなくてもいいと思います。
あとがき
要不要についてサクッと見切りをつけて、Hello Vueしてみてください!
Vueはいいぞ!
変更履歴
3/7 13:00頃:この文章の対象者と目標とするレベル感について加筆しました
3/7 未明:細かい表現の修正、編集リクエストのマージ
3/8 1:30頃:Nuxt.jsに対する批評があまりにも辛辣かつ曖昧だったので、入門者にオススメしない理由と導入すべきタイミングについて加筆しました