初学者がVue.jsをポートフォリオに組み込んだのでポイントをメモしておく


前提

ここではVue.jsのひとつひとつの単語を詳しく説明したりはしません。
あくまで実装していく上で気づいたポイントなどをメモしました。

Vue.jsの全体的なポイント

コンポーネントの構成

上記のコンポーネント構成図はあくまで僕のパターンですが、最初のうちは複雑で捉えきれない方(僕がそう)もいると思うので、一つの参考にしていただければと思い掲載しました。
コンポーネントの全体図を頭にいれておくと、開発がスムーズになると思います。

コンポーネント間のデータの受け渡し

上の図のように、
子コンポーネントから親コンポーネントへデータを渡すときは「emit」を利用し、
親コンポーネントから子コンポーネントへデータを渡すときは「props」を使用します。

ただしコンポーネントはお互いが疎結合(コンポーネント同士の結びつきが緩やかで、お互いが独立している状態)であることが望ましいので、コンポーネント間のデータ移動に制限があります

それは「兄弟コンポーネント間での直接のデータのやりとりはできない」というものです。

たとえば、BコンポーネントからDコンポーネントへデータを渡すには、直接データを輸送することはできず、「emit」や「props」を利用して、図のようにかなり遠回りしながらデータを渡すことになります。
(しかしこの制限のおかげで、コンポーネント間の依存関係などあまり配慮せずに、コンポーネントの交換や改良を柔軟に行えます)

ただ、これではあまりにも冗長的でコンポーネントが増えるとデータ輸送がさらに複雑になります。

そこでこのようなデータの受け渡しを解決するのが「Vuex」です。
Vuexとはデータの保管場所のことです。
図のようにVuexを介すことで、コンポーネントBのデータをコンポーネントDがスムーズに参照できるようになります。

非同期通信の流れ

・ユーザーが何かしらの入力(ボタンを押したり)をする
・Vue.jsでその入力を検知し、それに紐づくメソッドが発火する
・メソッド内の処理でAPIリクエストを実行する
・サーバーがリクエストに応じて該当の処理を行い、レスポンスを返す
・レスポンスに応じて処理を分ける
 ・正常レスポンス
  その後の処理を通常通り行う
  storeにデータを保管したり、dataオプションにデータを格納したり、$routerでコンポーネントを切り替えたり
 ・異常レスポンス
  errorsストア(ステータスコードを保管するためのストア)のステートにレスポンスに含まれるステータスコードを保存
  ルートコンポーネントにerrorsストアを監視させ、ステートに変更が確認された場合、そのステートの値(ステータスコード)に応じて条件分岐させ、そのステータスコードに応じたエラーページに切り替える

発火するメソッドの中身の例を以下に書いておきます。
グループ作成APIです。
別のファイルでexport const CREATED = 201と定義して、それをインポートしています。

methods: {
  //グループ作成処理
  async submit() {
    // APIリクエスト
    const response = await axios.post('グループ作成処理APIルーティング')
    // 異常レスポンスである場合、errorsストアにステータスコードを保存
    if( response.status !== CREATED) {
      this.$store.commit('error/setCode', response.status)
    }
    // 正常レスポンスである場合、予定通りの処理を行う
    this.$router.push('遷移先のルーティング')
  }
}

Vue.jsの実装に関した具体的なポイント

リロードしたときにログイン状態を保持させる

Vuexを利用してログイン状態を管理してる場合、リロードするとそのログイン状態がリセットされてしまいます。
これは、リロードするとVueアプリケーションが再生成され、Vueのあらゆるデータが初期値に戻ってしまうためです(ただし、サーバーサイドのセッションは残っています)。

この解決方法は以下のステップを踏みます。

① ログインユーザーを返すAPIを用意する

Route::get('/user', fn() => Auth::user())->name('user');

② ストアで①のAPIを呼ぶアクションを追加し、そのAPIレスポンス(ログインユーザー情報)をステートにセットする

const actions = {
  async currentUser (context) {
    const response = await axios.get('/api/user')
    const user = response.data || null
    context.commit('setUser', user)
  }
}

上記では、①のAPIを呼ぶアクションとして「currentUser」アクションを追加しています。
ログインしていない場合は、nullをステートにセットします。
ステートに値をセットする際は、ミューテーションを介して行います。

③ Vueアプリケーション生成前に②のアクションを呼び、あらかじめログインユーザーをステートにセットしておく

const createApp = async () => {
  await store.dispatch('auth/currentUser')

  new Vue({
    // 省略
  })
}

createApp()

必ず「currentUserアクション」を実行した後にVueアプリケーションを生成したいので、currentUserアクションをawaitして、Vueアプリケーションを生成する必要があります。
awaitを利用するには、asyncメソッドの内部にいる必要があるので、この一連の処理をasyncメソッド内に記入し、それを呼び出せるように関数化します。

最後にその関数(createApp)をセットしておくことで、起動時に必ずcreateApp関数は呼び出され、「ログインユーザーをステートにセットした後に、Vueアプリケーションを生成する」、つまりリロードしてもログインユーザーを保持することが実現できます。

いいね機能

Laravel + Vue.js でいいね機能を実装してみる

モーダルウインドウ

Laravel + Vue.js でモーダルウインドウを実装してみる

フラッシュメッセージ

Vueにおけるフラッシュメッセージ表示のロジック

エラーページの表示

Laravel + Vue.js エラーレスポンスを受けとった際にページを切り替える

最後に

ここまで読んでいただきありがとうございました。
誰かの参考に少しでもなれば幸いです。
何かミスや理解不足の部分がありましたら、気軽にコメントください。