vue.jsとFirebaseでSlackクローン構築(Tailwind CSS編)

vue.jsとFirebaseのRealtime DatabaseとAuthorization機能を利用したSlackクローンの構築を複数回にわけて行っています。2回目となる今回は認証に必要となるユーザ登録画面、サインイン画面(ログイン画面)をTailwind CSSを利用して作成していきます。本文書ではTailwind CSSを利用していますが、Tailwind CSSは必須ではありません。style.cssシートを利用してサインイン画面を作成することも可能です。
本文書を読みすすめる前に下記の文書を確認することをおすすめしますがTailwind CSSを理解しなくても本文書の指示通りにしていけばサインイン画面を作成することが可能です。
最終的には下記のユーザ登録画面とサインイン画面の作成します。


目次
Tailwind CSSのインストールと設定
Tailwind CSSをvue.jsの中で利用するためにはTailwind CSSのインストールと初期設定が必要になります。
npmコマンドを利用してtailwindのインストールを行います。taiwindのバージョン1.9をインストールしています。
$ npm install tailwindcss@1.9

vue.jsプロジェクトディレクトリのsrc¥assetsの下にcssディレクトリその下にtailwind.cssファイルを作成します。tailwind.cssファイルには下記を記述します。
@tailwind base;
@tailwind components;
@tailwind utilities;
次にtailwindの設定ファイルの作成を行います。カスタマイズをする場合に必要になるファイルです。
$ npx tailwindcss init
実行後tailwind.config.jsファイルが作成されます。次にpostCSSのプラグインとしてtailwindを追加するためにプロジェクトフォルダ直下にpostcss.config.jsファイルを作成します。作成したファイルに以下を記述します。
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
]
}
最後にmain.jsファイル内で先程作成したtailwind.cssファイルをimportします。
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import firebase from "firebase/app";
import "./assets/css/tailwind.css" //追加
・
・
tailwindの設定は完了です。ブラウザで確認するとtailwindの設定が反映されたことによりボタンの枠が消えていることが確認できます。またはh1タグで記述した”Firebaseを使った読み書き確認”の文字が通常のサイズになっていることが確認できます。もし文字に変化がない場合はnpm run devコマンドを再実行してみてください。

画面の作成
プロジェクトを作成する際にRouter機能をインストールしたのでルーティングが事前に設定されています。画面はすべてを一から作成をしていくためsrc¥App.vueファイルに記述されているRouterに関するrouter-linkタグやstyleタグを削除します。
<template>
<div id="app">
<router-view />
</div>
</template>
ルーティングの追加
画面の作成を行う前にルーティングファイル(router¥index.js)へのユーザ登録とサインインへのルーティングを追加します。URLはユーザ登録が/register、サインインが/signinとします。
デフォルトで存在するルーティングaboutの下に2つのルーティング情報を追加します。
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: "/register",
name: "register",
component: Register
},
{
path: "/signin",
name: "signIn",
component: SignIn
}
追加したルーティング情報に記載したコンポーネントRegesterとSignInをimportします。各ファイルは後ほどsrc¥componentsの下に作成します。
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Register from '../views/Register.vue'
import SignIn from '../views/SignIn.vue'
コンポーネントファイルの作成
viewsの下にRegister.vueとSignIn.vueファイルを作成します。作成時のファイルの内容はどちらも下記の通りです。本文書ではtemplateタグのみ追加していきます。
<template>
<h1>Slock Clone</h1>
</template>
<script>
export default {};
</script>
ブラウザで/registerにアクセスすると下記の画面が表示されます。

ヘッダーの作成
左側にSlack Cloneの文字と右側にサインインのボタンを表示させるためにヘッダーにはFlexboxを利用します。tailwindではclassにflex、justify-betweenを追加することで左右に要素を配置することができます。
<template>
<header class="flex justify-between">
<h1>Slack Clone</h1>
<button>サインイン</button>
</header>
</template>

Slack Cloneの文字の大きさや太さをtailwindのclassを利用して調整します。
<h1 class="font-semibold text-xl leading-tight">Slack Clone</h1>
ボタンはborderをグリーンとして、paddingをpx(paddingのx方向)とpy(paddingのy方向)を使ってスペース調整しています。roundedはボタンに丸みをつけるために設定しています。
buttonタグの中ではrouter-linkでsigninページへのリンクも設定します。
<button class="py-1 px-4 border-2 border-green-800 rounded">
<router-link to="/signin">サインイン</router-link>
</button>
その結果下記のように表示されます。

左右にスペースをとるためpadding、下部にborder、文字列を中央に揃えるためにitems-centerをheaderタグに追加します。
<header class="flex justify-between p-4 border-b items-center">

ここまででヘッダー部分の作業は完了です。
ユーザ登録部分の作成
ヘッダーの背景とユーザ登録部分の背景を分けるためにヘッダーをdivで囲みヘッダーとユーザ登録部分の領域をわけます。
ユーザ登録部分の背景のみ薄いグレーを設定します。
<template>
<div>
<header class="flex justify-between p-4 border-b items-center">
<h1 class="font-semibold text-xl leading-tight">Slack Clone</h1>
<button class="py-1 px-4 border-2 border-green-800 rounded">
<router-link to="/signin">サインイン</router-link>
</button>
</header>
<div class="bg-gray-100">ユーザ登録部</div>
</div>
</template>
ブラウザで確認すると背景はグレーになっていますが、文字がある箇所のみの背景しか色がついていないのでFlexboxを利用してユーザ登録部がすべてグレーになるように設定します。

先程追加したdivタグにflexのcolumn設定とh-screen(height:100vh)を設定し、ユーザ登録部分のdivタグにflex-autoを追加します。
<template>
<div class="flex flex-col h-screen">
<header class="flex justify-between p-4 border-b items-center">
<h1 class="font-semibold text-xl leading-tight">Slack Clone</h1>
<button class="py-1 px-4 border-2 border-green-800 rounded">
<router-link to="/signin">サインイン</router-link>
</button>
</header>
<div class="bg-gray-100 flex-auto">ユーザ登録部</div>
</div>
</template>
ブラウザで確認するとユーザ登録部の背景がすべてグレーになっていることが確認できます。

登録の入力フォームを追加
背景の設定が完了したので登録の入力フォームの設定を行います。
ユーザ登録の文字を画面中央に表示させるためflexのjustify-centerを設定し、ユーザ登録の文字列の大きさと太さをh2タグに設定します。
<div class="bg-gray-100 flex-auto">
<div class="flex justify-center mt-16">
<h2 class="text-4xl font-bold">ユーザの登録</h2>
</div>
</div>
画面中央にユーザ登録が表示されることが確認できます。

ユーザの登録の領域に幅、borderをもたせ背景を白に設定するために以下のclassを設定します。
<div class="bg-gray-100 flex-auto">
<div class="flex justify-center mt-16">
<div class="w-2/5 border bg-white">
<div class="my-12 text-center">
<h2 class="text-4xl font-bold">ユーザの登録</h2>
</div>
</div>
</div>
</div>
文字が中央に配置され背景が白になっていることが確認できます。

メールとパスワードの入力の文言を追加します。
<h2 class="text-4xl font-bold">ユーザの登録</h2>
<p class="my-4">
<span class="font-semibold">メールアドレス</span>と
<span class="font-semibold">パスワード</span>を入力してください。
</p>

最後に先ほど追加したpタグの閉じタグの下にfomタグでメールアドレスとパスワードの入力フォームを追加すると画面の完成です。フォーム内で使用しているtailwindのclassはpadding、marginやborderなどここまでで使用してきたものです。
<form>
<div class="mb-2">
<input
type="email"
placeholder="you@example.com"
class="text-xl w-3/5 p-3 border rounded"
/>
</div>
<div class="mb-2">
<input
type="password"
class="text-xl w-3/5 p-3 border rounded"
placeholder="パスワード"
/>
</div>
<button type="submit" class="text-xl w-3/5 bg-green-800 text-white py-2 rounded">ユーザの登録</button>
</form>
追加後にブラウザで確認すると以下のユーザ登録画面が表示されます。

サインイン画面の作成
サインイン画面はユーザ登録画面と内容はほぼ同じで表示される文言と右上にあるサインインのルーティング先を/registerに変更します。tailwindのclassなどの変更は行っていません。Register.vueファイルの内容をコピー&ペーストするか下記のコードをSignIn.vueファイルにコピー&ペーストしてください。

<template>
<div class="flex flex-col h-screen">
<header class="flex justify-between p-4 border-b items-center">
<h1 class="font-semibold text-xl leading-tight">Slack Clone</h1>
<button class="py-1 px-4 border-2 border-green-800 rounded">
<router-link to="/register">Slack Cloneをはじめる</router-link>
</button>
</header>
<div class="bg-gray-100 flex-auto">
<div class="flex justify-center mt-16">
<div class="w-2/5 border bg-white">
<div class="my-12 text-center">
<h2 class="text-4xl font-bold">サインイン</h2>
<p class="my-4">
<span class="font-semibold">メールアドレス</span>と
<span class="font-semibold">パスワード</span>を入力してください。
</p>
<form>
<div class="mb-2">
<input
type="email"
placeholder="you@example.com"
class="text-xl w-3/5 p-3 border rounded"
/>
</div>
<div class="mb-2">
<input
type="password"
class="text-xl w-3/5 p-3 border rounded"
placeholder="パスワード"
/>
</div>
<button type="submit" class="text-xl w-3/5 bg-green-800 text-white py-2 rounded">サインイン</button>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
ブラウザで確認するとサインイン画面が表示されます。

画面の移動
Register.vue、SignIn.vueの2つファイルを更新することでユーザ登録、サインインページを作成することができました。
各画面で右側のリンクをクリックすると各画面に相互に移動できることを確認してください。
サインイン画面なら右上の”Slack Cloneを始める”ボタンをクリックするとユーザ登録画面、ユーザ登録画面なら右上の”サインイン”ボタンをクリックするとサインイン画面に移動します。ページを移動する際は画面のリロードは行われないのでスムーズに移動が行われます。
これでユーザ登録画面とサインイン画面の作成は完了です。次は作成した画面にユーザ認証機能の追加を行っていきます。