Nuxt.jsとVuetifyでログイン画面を実装する

タイトル通りNuxt.jsとVuetifyで以下の様なログイン画面を実装します。実装するのは見た目だけで認証処理には触れません。

環境

バージョンは以下になります。

  • @nuxt/cli v2.15.8
  • vuetify@2.5.9

プロジェクト作成

Nuxtのプロジェクトは以下の設定で作成しました。Vuetifyも一緒に用意しています。

テキストフィールドのコンポーネント化

メールアドレスとパスワードを入力するテキストフィールドを用意します。これらのテキストフィールドはログイン画面以外でも使いまわせそうなのでコンポーネントとして作成します。

Componentsフォルダの中にTextFieldComponentsという名前でフォルダを作成し、EmailField.vueとPasswordField.vueという名前でファイルを作成します。

まずはシンプルにpropsで親コンポーネントから受け取る値をv-text-fieldに引き渡します。

画面の確認

作成したテキストフィールドを試しに画面表示してみます。pagesフォルダにlogin.vueファイルを作成します。

login.vueを次の様に編集します。先ほど作成したテキストフィールドを表示しているだけの画面です。

見た目はこんな感じになります。

この状態でテキストフィールドに何か値を入力すると「[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "email"」と以下の様な警告がDevToolsに表示されています。

propsの値を子コンポーネントの中から変更しないでね、と言われていますのでこれに対応します。

警告の対応

子コンポーネントで直接変更するのではなく、変更があったら親コンポーネントへ通知(emit)するようにします。また、v-modelだとv-text-fieldで変更があった場合に値を更新しようとしてしまうため:valueに変更します。

親コンポーネントでは.sync修飾子を付けて、子コンポーネントからの更新通知を自分の持ってるデータに反映させます。

参考 カスタムイベント — Vue.jsカスタムイベント — Vue.js

以下の様なコードになります。5行目はただの確認用です。

ちゃんと各データが反映されていることが確認できます。

メモ
.sync修飾子はNuxt3(正確にはvue3)では廃止されます。 参考 v-model | Vue.jsv-model | Vue.js

メールアドレス入力欄のお化粧

少しお化粧しておきます。入力欄の前方にメールのアイコンを表示するようにしました。

パスワード入力欄のお化粧

パスワード入力欄もお化粧していきます。

こんな感じの見た目になります。

5行目:prepend-icon="mdi-lock"

入力欄の前方に鍵のアイコンを表示しています。

6行目::append-icon="show ? 'mdi-eye' : 'mdi-eye-off'"

入力欄の後方に目のアイコンを表示しています。下図のようにshowの値に応じてアイコンが切り替わるようになっています。

7行目::type="show ? 'text' : 'password'"

上図のようにshowの値に応じて入力欄をマスクするか指定してします。

8行目:hint="最小8文字"

フォーカスされた時に表示するメッセージを指定しています。

9行目:counter

入力欄右下に入力文字数が表示されるようになります。

10行目:@click:append="show = !show"

append要素がクリックされたらshowの値のtrue/falseを切り替えます。

24~28行目

変数showを定義しています。

フォームのコンポーネント化

ログインフォームを作っていきます。再利用できるようにコンポーネントとして作成します。

componentsフォルダにFormComponentsというフォルダを作成し、LoginForm.vueという名前でファイルを作成します。

中身を次の様に編集します。v-cardでレイアウトしている以外は先ほどのlogin.vueとほとんど同じですので一部のみ補足します。

15行目:<v-btn @click="submit">ログイン</v-btn>

ログインボタンを配置し、クリックイベントでsubmitメソッドを呼んでいます。

32~36行目

15行目で呼ばれるsubmitメソッドが定義されています。ここでサーバーへの認証要求を投げることになりますがここではそこまで実装しません。

ログイン画面からログインフォームコンポーネントを使う

作成したLoginForm.vueをlogin.vueから利用します。コンポーネントを配置するだけです。

見た目はこんな感じです。ここからレイアウトや背景画像を編集していきます。

レイアウトの編集

ログイン画面からメニューバーは取り除こうと思います。そのためオリジナルのレイアウトファイルを作成します。layoutsフォルダにLoginLayout.vueという名前でファイルを作成します。

中身は次の様に編集します。5行目でfill-heightを指定することで上下中央寄せしています。

vuetifyで背景画像を設定する方法が見つからないので次のページのコードをコピペしました。

レイアウトの適用

作成したレイアウトをlogin.vueから使用するように指定します。

2行目:<LoginForm class="mx-auto" />

mx-autoで中央寄せしています。

8行目:layout: "LoginLayout",

作成したレイアウトを使うよう指定しています。

仕上げ

こんな感じの見た目に仕上がりました。darkテーマのままなのでnuxt.config.jsでテーマをdark:falseにします。

darkをfalseにセット。

白っぽくなりました。

最後に

本来であれば入力値のチェックをしなければならないですがそこは次の記事でやろうと思います。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です