https://gyazo.com/ea52c6afc3760e36f4c4e6c1caed0d62
https://www.youtube.com/watch?v=HPsVAakHXCU
Go Tadano
フロントエンドエンジニア
いつやるか?なぜやるのか?
プロジェクトが予想より大きくなった
リファクタリングの効率化
副作用に怯えない
TypeScriptのサポート強化
まだつくったことがない
学び
vue add @vue/typescript
依存モジュールは2つイエス
差分にtsファイルが生成される
同名のファイルは上書きされる
Vuex Module
この時点でコンパイラエラーが発生してる
型をつけてあげる
2. TypeScriptを使用したVueコンポーネントの実装
<script lang="ts">
デコレータを仕様
@Componentを使うとメタデータがクラスに渡される
data, methods, components, mixinなど
JSXをTSX化
拡張子を.tsxに変更
すぐにコンパイルエラーが発生するので修正
render関数
引数、戻り数に型をつける
イベントハンドラーに型定義
コンポーネントをローカル登録
componentsキー
3. Vuexモジュールの作成
クラスベースで実装する
vuex-module-decorators
configのtranspileDependenciesに追加
名前空間付きであることを明示
namespaced: true
state => publicクラスプロパティ
mutations => @Mutationを付与したクラスメソッド
getters => クラスのgetter
4. Vuexとコンポーネントのバインド
vuex-class
名前空間のデコレータを作成
Vuexプロパティとバインド
同じ型・名前のクラスプロパティ
getters, mutationsも同じ宣言
Vuex mutationsは関数型
宣言時に初期化しないとエラー
クラスプロパティの型チェック
適当な型でも通ってしまう
イベントハンドラーの型定義
プロジェクト構成
まとめ
Vuex ModuleがTSのクラスベース実装になった
問題点
関数の戻り値型を定義しなくてもコンパイルエラーにならない
Vuex Moduleとバインドするクラスプロパティの型チェックが行われるかが課題
propsについて考える
SatohJohn
サーバサイド、フロントエンド、インフラ
propsってどこまで書いてる?という疑問
propsってどんなもの?
前提
コンポーネントに渡る値を明示する
Required
必須かどうかを検証
Type
型の検証
複数指定できる
違う方が入るとwarnがでる
Validator
コンポーネントに渡る値の検証
falseを返すとwarnが出る
TypeでエラーならValidatorでの検証は動かない
Default
入力値がなかった場合のデフォルト値
Default値があったらRequiredは動かない
ただし検証も対象にする
メリット
コンポーネントを「具体的な」実装で表せる
具体的=コードがドキュメントである
ドキュメントで説明ではなく実装で説明する
Whyなどを完全に書くのは難しいので、完全なドキュメントにはならない
Required=必須
Validator=条件
Type=型
インタフェースとして定義できる
依存関係逆転の法則
上位モジュールは下位のモジュールに依存してはならない
抽象(インターフェース)に対して依存する
インターフェース=propsと捉えている
結合が減らせるので修正が容易に
親=>子
子コンポーネントが自分propsに依存する
propsの値を変更するとエラー
propsで渡されると親子間でのデータ渡ししかができない
storeをかませると依存が増える
なるべくpropsで済ませて完結にする
Validatorのロジックをどこに書くか
ViewModelに書く
Validatorに直接書くと流入しにくい
LogicとViewを分割して考える
ガッチリやりすぎると固くなるので程々に
まとめ
propsはとても良い機構
今のSPA
モダンフロントライブラリを利用
リッチUIを1ファイルのJSで表現
静的なhtmlとセットで簡単に配信できる
よくある質問
Vuex使っとけばいいの?
どうコードを書くのが正解なの?
せっかくなのでVuexがあると明確に助かるケースを紹介
mutationsからしか変更できないように保護してくれる
サーバー側でHTMLを生成して返す
JSを埋め込んでリッチなUIを表現
ページを変えるたびにサーバーに新たなHTMLを要求
代表例
ファーストペイントを早くする方法の1つを紹介
従来のSSRのようにサーバー側で生成して返す
利点
ネットワーク的に近い距離からAPIが叩ける
比較的安定しているコンピューター上で初期描画が行える
サーバー利用に制限されたAPIを叩ける
仕組み
結果が同じなので生成された要素をフロントのVueが引き継げる
https://gyazo.com/4a2ada76a9a16ed78aaec0f989fe6a46
構造が違うとhydrationに失敗する
課題
サーバーからフロントにコンポーネントの状態を正しく復元する必要性
状態をjson化してwindowのstateに突っ込むなど ライフサイクルまとめ
サーバー
serverPrefetch
beforeCreate
created
フロント
replaceState
ライフサイクルではない
beforeCreate
created
beforeMount
まとめ
SPAとSSRでコードの書き方は全然違うので気をつけよう
SSRする場合はcreatedの扱いは細心の注意が必要
serverで実行したいコードはserverPrefetchを使おう
nuxtの場合はasyncData等
フロントでmount後にやりたい事はmountedでやろう
シングルトンは危ない
ページ個別にOGPを設定するには?
headでメタタグ設定
Universalモードに切り替える場合
fetchでのwindow object操作が全滅
一部設計やりなおし
検証コストが増える
できそうな感じらしい
方針
nuxt startしないプロジェクトを目指す
サーバーが起動するので改ざんの余地なし
node app.jsで動かす
HTMLを取得したい
nuxt.renderRoute()
実質テンプレートが取得できる
返り値のオブジェクトに含まれるHTMLにレンダリングしようとしたHTMLが入ってる
特定のルーティングの場合
expressのapp.get()を使用する
特定のときだけエンドポイントが動く
改ざんしてレンダリング
String.replace()でゴリゴリ変換
置換したものをres.send()でレンダリング
メリット
以降に比べれば検証コストが軽い
サーバーでDOMの計算をしなくていい
デメリット
ページコンポーネントのルーティングと改ざん処理のルーティングが一致しない
自動ルーティングの恩恵が得られない
1ページの処理が2箇所になる