このチャプターで達成すること
チャプター「ログイン後のレイアウト構築」では、ログイン後の各ページを作成します。
それと同時に、
- inject機能を使った共通メソッドの作成
- ページファイルの子コンポーネント化
など、Nuxt.jsの実務的な知識と実装方法を学びます。
ログイン後のレイアウトファイル設計
ログイン後に使用するレイアウトファイルは3つあります。
レイアウトファイル | 使用するページ |
---|---|
loggedIn.vue | プロジェクト一覧ページ、アカウントページ |
logout.vue | ログアウトページ専用 |
default.vue | プロジェクトページ |
レイアウトファイル自体は何個作成しても問題ないですが、大切な事は「プロジェクトページ」とその他のページを分離することです。
上記のように分離することで、構築から運用までが楽に行えます。
今後のNuxtアプリ構築の参考にしてください。
本チャプターで構築するページ
なお、本チャプターで構築するページは、
- プロジェクト一覧ページ
- ログアウトページ
- プロジェクトページ
の3つです。
アカウントページは作成しますが、レイアウト構築の予定はありません。
それでは実装に入りましょう!
今回達成すること
ログイン後のツールバーを作成します。
また、Nuxt.jsのinjectを使った共通メソッドの作成方法についても解説します。
完成イメージ
ログイン後のレイアウトファイルを表示する
まずは、ログイン後のレイアウトファイルを表示するところまでを行いましょう。
ここで作成するレイアウトファイルは、
- トップページと
- アカウントメニューページ
で使用します。
レイアウトファイルを作成する
「layouts」ディレクトリに
root $ touch front/layouts/loggedIn.vue
front/layouts/loggedIn.vue
<template>
<v-app>
<logged-in-app-bar />
<v-main>
<nuxt />
</v-main>
</v-app>
</template>
<script>
export default {
}
</script>
ツールバーコンポーネントを作成する
呼び出された
ログイン後のコンポーネントファイルは「loggedIn」ディレクトリで管理します。
「components」ディレクトリに、
- 「loggedIn」ディレクトリと、
- その下に「header」ディレクトリを作成し、
- その直下に
loggedInAppBar.vue を作成しましょう。
front $ mkdir -p front/components/loggedIn/header && touch $_/loggedInAppBar.vue
-p
... 子ディレクトリも一度に作成する。
作成した
front/components/loggedIn/header/loggedInAppBar.vue
<template>
<v-app-bar
app
dense
elevation="1"
clipped-left
color="white"
>
<nuxt-link
to="/"
class="text-decoration-none"
>
<app-logo />
</nuxt-link>
<app-title />
</v-app-bar>
</template>
<script>
export default {
}
</script>
ログインフラグをtrueにする
ログイン後のレイアウトを確認できるよう、true
に変更しておきます。
この編集は一時的なものです。
front/store/index.js
export const state = () => ({
// trueに変更
loggedIn: true,
...
})
...
Index.vueのレイアウトを編集する
トップページのレイアウトメソッドを編集します。
現状はログイン後のレイアウトがdefault
になっているので、これをloggedIn
に変更します。
front/pages/index.vue
...
<script>
export default {
layout ({ store }) {
// loggedInに変更
return store.state.loggedIn ? 'loggedIn' : 'welcome'
// return store.state.loggedIn ? 'default' : 'welcome'
}
}
</script>
確認してみよう
コンテナを起動して、http://localhost:8080/ にアクセスしてください。
トップページに
ツールバーにアカウントメニューを作成する
作成したツールバーに、アカウントメニューへのリンクを作成します。
<app-title />
下に、Vuetifyの<v-menu>
を追加します。
front/components/loggedIn/header/loggedInAppBar.vue
<template>
...
<app-title />
<!-- 追加 -->
<v-spacer />
<v-menu
app
offset-x
offset-y
max-width="200"
>
<template v-slot:activator="{ on }">
<v-btn
icon
v-on="on"
>
<v-icon>
mdi-account-circle
</v-icon>
</v-btn>
</template>
<v-list dense>
<v-subheader>
ログイン中のユーザー
</v-subheader>
<v-list-item>
<v-list-item-content>
<v-list-item-subtitle>
<!-- TODO -->
ユーザー名が表示されます
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider />
<v-subheader>
アカウント
</v-subheader>
<template v-for="(menu, i) in accountMenus">
<v-divider
v-if="menu.divider"
:key="`menu-divider-${i}`"
/>
<v-list-item
:key="`menu-list-${i}`"
:to="{ name: menu.name }"
>
<v-list-item-icon class="mr-2">
<v-icon size="22" v-text="menu.icon" />
</v-list-item-icon>
<v-list-item-title>
{{ menu.name }}
</v-list-item-title>
</v-list-item>
</template>
</v-list>
</v-menu>
<!-- ここまで -->
</v-app-bar>
</template>
<script>
export default {
// 追加
data () {
return {
accountMenus: [
{ name: 'account-settings', icon: 'mdi-account-cog' },
{ name: 'account-password', icon: 'mdi-lock-outline' },
{ name: 'logout', icon: 'mdi-logout-variant', divider: true }
]
}
}
}
</script>
ツールバーの右端にアカウントメニューが表示されました。
injectを使ってアプリ共通メソッドを追加する
現在のアカウントメニューは、正しく日本語化できていません。
そこでNuxt.jsのinjectの機能を使って、ルート名を日本語化するアプリ共通メソッドを作成します。
injectとは?
injectとは、オリジナルクラスをNuxt.jsに追加できる機能です。
クラス内で作成したメソッドは、Nuxtアプリのどこからでも呼び出せます。
主に、アプリ全体で使用するメソッドを管理するために使います。
プラグインファイルを作成する
injectはプラグインファイルとして作成します。
「plugins」ディレクトリ以下に
root $ touch front/plugins/myInject.js
オリジナルクラスを宣言する
front/plugins/myInject.js
class MyInject {
constructor (app) {
this.app = app
}
}
export default ({ app }, inject) => {
inject('my', new MyInject(app))
}
injectの使い方
まず、injectでNuxtに追加するオリジナルクラスを宣言します。
そのクラスをinject()
内で初期化します。
その時の第一引数のmy
がVueファイルからの呼び出し名となります。
この場合、this.$my.メソッド名
で呼び出すことができます。
Nuxt.jsのコンテキストも取得可能
コンテキストとは、asyncData()
などの引数で取れるapp
やstore
オブジェクトのことを言います。
Nuxt.jsが初めから用意しているものもあれば、モジュールの追加で使えるものもあります。
オリジナルクラスでコンテキストを使用する場合は、
- クラスを初期化する際に引数として渡し ...
new MyInject(app)
constructor
内で代入します。 ...this.app = app
これにより、Nuxt.jsのapp
がクラス内で使用できます。
日本語化メソッドの追加
アカウントメニューを日本語化するメソッドを追加しましょう。
front/plugins/myInject.js
class MyInject {
constructor (app) {
this.app = app
}
// 追加
// i18nページタイトル変換
pageTitle (routeName) {
const jsonPath = `pages.${routeName.replace(/-/g, '.')}`
const title = this.app.i18n.t(jsonPath)
return (typeof (title) === 'object') ? title.index : title
}
}
export default ({ app }, inject) => {
inject('my', new MyInject(app))
}
i18n
を使用して、多階層のルート名を日本語化するメソッドです。
プラグインファイルを登録する
プラグインファイルの読み込みは、
plugins
プロパティに追加してください。
front/nuxt.config.js
...
plugins: [
'plugins/axios',
// 追加
'plugins/myInject'
],
これでinjectを使ったアプリ共通メソッドの完成です。
アカウントメニューを日本語化する
それでは
front/components/loggedIn/header/loggedInAppBar.vue
...
<v-list-item-title>
<!-- 追加 -->
{{ $my.pageTitle(menu.name) }}
<!-- 削除 -->
<!-- {{ menu.name }} -->
</v-list-item-title>
</v-list-item>
</template>
</v-list>
</v-menu>
</v-app-bar>
</template>
ja.jsonに日本語の設定をする
front/locales/ja.json
{
...
"pages": {
"signup": "会員登録",
"login": "ログイン",
// 追加
"logout": "ログアウト",
"account": {
"settings": "アカウント設定",
"password": "パスワード変更"
}
}
}
これでアカウントメニューが日本語化されました。
コミットする
以上で作業は終了です。
「front」ディレクトリをコミットしておきましょう。
root $ cd front
front $ git add -A
front $ git commit -m "add_loggedIn_toolbar"
front $ cd ..
root $
まとめ
今回はログイン後のツールバーを作成しました。
Nuxt.jsの共通メソッドの作成は、injectの他にもVuexのgetters
を使う方法やVueのfilter
機能を使う方法があります。
しかし、
getters
はコンテキストが参照できない、filter
はメソッドというか値変換用の機能
というように、共通メソッドの作成に向いていない点があります。
やはり共通メソッドの作成は、1つのクラスとして管理する「inject」がおすすめです。
次回は?
アカウントメニューページとログアウト機能を実装します。
子コンポーネントを使ったページのレイアウト方法も解説していきます。
どうぞおたのしみに。