SPA開発 8. ログイン周りのレイアウト設計 #01
2020年01月05日に更新

【Nuxt.js】ログインフラグでレイアウトを切り替えるテクニック【2019/12/07追記あり】

【2019/12/07追記】ログイン後のfooter.vueは使用しないとしました。

ログイン後のfooter.vueは、2つの理由で使用しない事としました。

  1. 重要性がないこと
  2. <v-navigation-drawer>と併用した時に下に固定表示され、ユーザーが見る画面領域が狭まる事

この変更に伴い、レイアウトファイルのdefault.vueを以下のように変更しました。

frontend/layouts/default.vue
<template>
  <v-app>
    <login-header />
    <nuxt />
    <!-- <my-footer /> 削除 -->
    <my-footer v-if="!$store.state.loggedIn" />	<!-- 追加 -->
  </v-app>
</template>

なお、記事は修正済みの内容となっています。

今回達成すること

今回はNuxt.jsのlayoutプロパティを使って、ログイン前と後でレイアウトを切り替えていきます。

完成イメージのgif

switching layout

レイアウトファイルの設計

レイアウトファイルは、ログインの前後でこのように切り替えます。

なお、default.vue以外のファイルは全て作成します。

ログイン前 ログイン後
レイアウトファイル home.vue default.vue
ヘッダーコンポーネント shared/header.vue shared/loginHeader.vue
フッターコンポーネント shared/footer.vue 同左 不要

ブランチを作成しときましょ

新しい作業に入るのでブランチを作成しておきましょう。

myapp $ git checkout -b login_layouting

作業に移る前に

今回の記事は全てNuxt.js上での作業となります。

ターミナルは、Rails内のNuxt.jsプロジェクト(筆者の場合、myapp/frontend)に移動しておいてください。

froutend $ # ここに移動しておく

それでは実装に移りましょう。

Eslintのルールを緩和する

まず、実装の前にEslintのルールを変更します。

確認のたびにエラーを吐き出されると困る2つのルールを緩和します。

  1. no-console

    console.logがある時にエラーを吐きます。

    warn(警告)に変更します。

  2. vue/no-unused-components

    template内で使われていないコンポーネントがある時にエラーを吐きます。

    warn(警告)に変更します。

frontend直下.eslintrc.js内のrulesプロパティにルールを追加します。

ちなみにルール付けは、error(エラー)、warn(警告)、off(何もしない) の3つを設定する事ができます。

frontend/.eslintrc.js
module.exports = {
  ...
  rules: {
    'no-console': 'warn', // 追記
    'vue/no-unused-components': 'warn'  // 追記
  }
}

componentsファイルの作成

componentsディレクトリにsharedディレクトリを作成し、その下3つのファイルを作成します。

  1. loginHeader.vue
  2. header.vue
  3. footer.vue
frontend $ mkdir components/shared && touch components/shared/{loginHeader.vue,header.vue,footer.vue}
  • touch {file1, file2, file3}

    touchコマンドで同じディレクトリ内に複数のファイルを一度に作成するテクニックです。

componentsディレクトリはこのようになります。

components
├── README.md
└── shared
    ├── footer.vue
    ├── header.vue
    └── loginHeader.vue

デフォルトで入っているlogo.vueは、必要ないので削除しました。

componentファイルの編集

作成した3つのファイルを以下のように編集しましょう。

frontend/components/shared/loginHeader.vue
<template>
  <div>
    ログイン後のloginHeader.vueを表示中
  </div>
</template>

<script>
export default {
}
</script>
frontend/components/shared/header.vue
<template>
  <div>
    ログイン前のheader.vueを表示中
  </div>
</template>

<script>
export default {
}
</script>
frontend/components/shared/footer.vue
<template>
  <div>
    footer.vueを表示中
  </div>
</template>

<script>
export default {
}
</script>

これでコンポーネントファイルが整いました。

layoutファイルの作成

ログイン前のトップページとして利用するhome.vueを作成します。

layoutsディレクトリ内に作成しましょう。

frontend $ touch layouts/home.vue

layoutsディレクトリはこのようになります。

frontend/layouts
├── README.md
├── default.vue
└── home.vue

ログイン前のレイアウト(home.vue)を編集

ログイン前のトップページとして利用するhome.vueから、ヘッダーとフッターコンポーネントを呼び出します。

ログイン前のヘッダーは「header.vue」を利用するので間違わないようにしてください。

frontend/layouts/home.vue
<template>
  <v-app>
    <my-header />
    このページはログイン前のレイアウト「home.vue」が使用されています。
    <my-footer />
  </v-app>
</template>

<script>
import myHeader from '~/components/shared/header.vue'
import myFooter from '~/components/shared/footer.vue'

export default {
  components: {
    myHeader,
    myFooter
  }
}
</script>

ログイン後のレイアウト(default.vue)を編集

ログイン後のレイアウトファイルdefault.vueからも同じくヘッダーとフッターを呼び出します。

ログイン後のヘッダーは「loginHeader.vue」を呼び出します。

frontend/layouts/default.vue
<template>
  <v-app>
    <login-header />
    <nuxt />
    <my-footer v-if="!$store.state.loggedIn" />
  </v-app>
</template>

<script>
import loginHeader from '~/components/shared/loginHeader.vue'
import myFooter from '~/components/shared/footer.vue'

export default {
  components: {
    loginHeader,
    myFooter
  }
}
</script>
  • <my-footer v-if="!$store.state.loggedIn" />

    ログインフラグがfalse、つまりログインしていない場合に表示します。

ログインフラグを扱うindex.jsファイルを作成する

ログインフラグをVuexに作成します。

storeディレクトリ内にindex.jsを作成しましょう。

frountend $ touch store/index.js

index.jsにloggedInを作成する

作成したindex.jsにログイン判定を行うフラグを作成します。

frontend/store/index.js
// 追記
export const state = () => ({
  loggedIn: false
})

レイアウトを切り替えるテクニック

それでは、index.vueにレイアウトを切り替える実装を行います。

と言っても簡単で、layoutプロパティに表示したいファイル名を文字列で渡します。

frontend/pages/index.vue
<script>
export default {
  // layoutプロパティを追記
  layout ({ store }) {
    return store.state.loggedIn ? 'default' : 'home'
  }
  ...
}
</script>

layout()には、layoutsディレクトリ内にあるファイル名を文字列で渡します。

また、単にレイアウトを変更する場合は以下のように書くことができます。

export default {
  layout: 'home'
}

ログインフラグを切り替えるリンクを作成する

ログインフラグを切り替えるリンクを作成していきましょう。

store/index.js

index.jsloggedInフラグを変更するactionメソッドを作成します。

frontend/store/index.js
export const state = () => ({
  loggedIn: false
})

// 以下、追記
export const mutations = {
  setLogin (state, payload) {
    state.loggedIn = payload
  }
}

export const actions = {
	userLogin ({ commit }, payload) {
		commit('setLogin', payload)
  }
}

ログイン、ログアウトページの作成

pagesディレクトリに、ログイン、ログアウトページを新たに作成します。

frontend $ touch pages/{login.vue,logout.vue}

pagesディレクトリはこのような構成になります。

pages
├── README.md
├── index.vue
├── login.vue
└── logout.vue

ログインページにリダイレクト設定を行う

/loginに遷移するとトップページにリダイレクトする設定を行います。

frontend/pages/login.vue
<template>
  <div />
</template>
<script>
export default {
  fetch ({ store }) {
    store.dispatch('userLogin', true)
  },
  created () {
    this.$router.replace('/')
  }
}
</script>
  • store.dispatch('userLogin', true)

    ログインページには、引数にtrueを渡しています。

  • this.$router.replace('/')

    ページ遷移と同時にトップページへ移動するよう設定しています。

ログアウトページにもリダイレクト設定を行う

こちらも同じく、/logoutに遷移するとトップページにリダイレクトする設定を行います。

frontend/pages/logout.vue
<template>
  <div />
</template>
<script>
export default {
  fetch ({ store }) {
    store.dispatch('userLogin', false)
  },
  created () {
    this.$router.replace('/')
  }
}
</script>
  • store.dispatch('userLogin', false)

    ログアウトページには、引数にfalseを渡しています。

トップページにリンクをセットする

home.vueには、/loginリンクをセットします。

frontend/layouts/home.vue
<template>
  <v-app>
    <my-header />
    このページはログイン前のレイアウト「home.vue」が使用されています。
    <!-- 追記 -->
    <nuxt-link to="/login">
      ログインする
    </nuxt-link>
    <!-- 追記終了 -->
    <my-footer />
  </v-app>
</template>
...

index.vueには、/logoutリンクをセットします。

frontend/pages/index.vue
<template>
  <v-container fluid fill-height>
    <v-row
      justify="center"
      class="text-center"
    >
      <!-- 追記 -->
      <v-col cols="12">
        <nuxt-link to="/logout">
          ログアウト
        </nuxt-link>
      </v-col>
      <!-- 追記終了 -->
      ...
</template>

最後に確認してみましょう

以上で実装は完了です。

Nuxt.jsを起動した後に"http://localhost:3333/"にアクセスして確認してみましょう。

frontend $ yarn dev

switching layout

コミットしとこ

さて、ここまでの変更をコミットしておきましょう。

一度Railsプロジェクトに戻ります。

frontend $ cd ../

commitしましょう。

myapp $ git add -A
myapp $ git commit -m "add_layout_files"

まだ、masterブランチにはマージしません。

まとめ

今回は、ログイン前とログイン後に利用する、レイアウトファイルとコンポーネントファイルを作成しました。

ログイン前 ログイン後
レイアウトファイル home.vue default.vue
ヘッダーコンポーネント shared/header.vue shared/loginHeader.vue
フッターコンポーネント shared/footer.vue 同左 不要

Nuxt.jsのレイアウトは、デフォルトでdefault.vueが読み込まれます。

このdefault.vueを主に利用するレイアウト設計をした方が、切り替え作業が最小に抑えられます。

頭の隅っこに覚えておいてください。

さて、次回は?

今のままだとかなりブサイクなので、次回はヘッダーとフッターを作り込んでいきます。

どうぞお楽しみに。

現在、カテゴリー「Rails apiとNuxt.jsでSPA開発」のデモアプリを構築中です。記事になるまでもう少々のお時間が必要です。ブログの更新が止まって申し訳ありません。デモアプリの進捗状況は こちらの記事 で随時お伝えしてまいります。
スポンサー広告
次の記事はこちらです
SPA開発
今日のTweet
スポンサー広告