Vue.js + Vuex + VuetifyとFirebaseでSPAを作る(その2)

2019-11-23TIPS,Vue.jsFirebase,Vuetify,Vuex

Vue, Vuex, VueRouter, Vuetifyおよび Firebase を使用してハリネズミ紹介 Web サイトを作成していきます。

上のヘッダー画像は作成するウェブサイトの完成図です。

各工程は以下の4部構成に分かれています。

これまでVueを使用したことがない初心者の方でも困らないよう詳しめに解説していきます。


前回行った内容

前回の投稿ではVue CLIを使用してVueアプリケーションを作成しました。
その後Vuetifyをアプリに追加し、ホームページのスタイル設定にVuetifyを使用しコンポーネントを利用しました。


Vue Router を使用する

Vue Router はアプリのナビゲーションを提供してくれます。
今回は サインインボタンをクリックするとログインするページにリダイレクトさせましょう。
そしてメニューボタンをクリックすると、パイルカラーごとのハリネズミを紹介するページにリダイレクトさせます。

router.js ファイルにはルーティングの構成が含まれており、ファイルを開くと2つのルートがあるはずです。
'/' ルートにアクセスしたときにHome.vueコンポーネントを表示するもの。
そしてもう1つはaboutにアクセスしたときにabout.vueコンポーネントを表示するものです。
今回作成する全てのページにルートを作成する必要があり、以下のルートが必要となります。

  • /
  • /menu
  • /sign-in
  • / join

Vue CLIを使用してアプリを作成したときにVue Routerのインストールを選択したと思いますが、デフォルトではホームページである「/」と「about」ページの「/about」のルートが作成されます。

よってまずは3つの新しいルートを追加する必要があります。
router.js を以下のように記述しましょう。

src/router.js

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
Vue.use(Router);
export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    },
    {
      path: "/about",
      name: "about",
      component: () => import("./views/About.vue")
    },
    {
      path: "/menu",
      name: "menu",
      component: () => import("./views/Menu.vue")
    },
    {
      path: "/sign-in",
      name: "signin",
      component: () => import("./views/Signin.vue")
    },
    {
      path: "/join",
      name: "join",
      component: () => import("./views/Join.vue")
    }
  ]
});


Viewを作成する

views と components の違い

最初の投稿ではいくつかの新しいVueコンポーネントを作成しcomponentsフォルダー内に配置しました。

しかし、先ほど作成したルートに紐づける3つの新しいコンポーネントについては、componentsフォルダーには作成しません。
代わりにをviewsフォルダー内に配置します。

/menu などURLを使用してアクセスされるものは全てviewsフォルダーに配置する必要があります。
そして前回作成したような1つのページ内で使用するためのパーツはcomponentsフォルダーに配置します。

3つのviewを作成する

それでは早速以下のファイルをviewsフォルダーに作成しましょう。

  • Menu.vue
  • Signin.vue
  • Join.vue

ファイルを作成したら以下を参照し各ファイルへコードを記述してください。
各ファイル内には<v-layout>と<v-container>を追加します。
またレイアウト内にはページ名を持たせた<h1>タグを用意します。

src/views/Menu.vue

<template>
  <v-container fluid>
    <v-layout>
      <h1>Menu Page</h1>
    </v-layout>
  </v-container>
</template>
<script>
export default {
  name: "Menu"
};
</script>
<style scoped>
</style>


src/views/Signin.vue

<template>
  <v-container fluid>
    <v-layout>
      <h1>Signin Page</h1>
    </v-layout>
  </v-container>
</template>
<script>
export default {
  name: "Signin"
};
</script>
<style scoped>
</style>


src/views/Join.vue

<template>
  <v-container fluid>
    <v-layout>
      <h1>Join Page</h1>
    </v-layout>
  </v-container>
</template>
<script>
export default {
  name: "Join"
};
</script>
<style scoped>
</style>

メニューをクリック可能にする

メニューにはユーザーがクリックできる4つのアイテムがあります。

  • Menu
  • Profile
  • Sign In
  • Join

ユーザーがクリックしたときに適切なページに移動するようにそれぞれを構成していきます。
まずはcomponentsフォルダー内の AppNavigation.vue ファイルを開きます。
そして各 v-btnタグに to = “/menu" とルーティング先を追加するだけでOKです。
すべてのエントリーに対しこれを行いますが、router.jsファイルで定義した正しいルートを指定するように注意してください。

今回、ホームページに戻るためのメニューオプションは用意してありません。
なのでアプリ名をクリックされた時にホームページにリダイレクトするようにします。

ただしタイトルはボタンではないため、to = “/menu" を追加しても機能しません!
でもVue Routerには <router-link to=”/”> でリンクを囲むオプションがあるのでこれをアプリタイトルに対して行いましょう。

上記の内容を記述したAppNavigationは以下のようになります。

src/components/AppNavigation.vue

<template>
  <span>
    <v-navigation-drawer app v-model="drawer" class="brown lighten-2" dark disable-resize-watcher>
      <v-list>
        <template v-for="(item, index) in items">
          <v-list-tile :key="index">
            <v-list-tile-content>{{item.title}}</v-list-tile-content>
          </v-list-tile>
          <v-divider :key="`divider-${index}`"></v-divider>
        </template>
      </v-list>
    </v-navigation-drawer>
    <v-toolbar app color="brown darken-4" dark>
      <v-toolbar-side-icon class="hidden-md-and-up" @click="drawer = !drawer"></v-toolbar-side-icon>
      <v-spacer class="hidden-md-and-up"></v-spacer>
      <router-link to="/">
        <v-toolbar-title to="/">{{appTitle}}</v-toolbar-title>
      </router-link>
      <v-btn flat class="hidden-sm-and-down" to="/menu">Menu</v-btn>
      <v-spacer class="hidden-sm-and-down"></v-spacer>
      <v-btn flat class="hidden-sm-and-down" to="/sign-in">SIGN IN</v-btn>
      <v-btn color="brown lighten-3" class="hidden-sm-and-down" to="/join">JOIN</v-btn>
    </v-toolbar>
  </span>
</template>

<script>
export default {
  name: "AppNavigation",
  data() {
    return {
      appTitle: "HedgeHogs 🦔 ",
      drawer: false,
      items: [
        { title: "Menu" },
        { title: "Profile" },
        { title: "Sign In" },
        { title: "Join" }
      ]
    };
  }
};
</script>

<style scoped>
</style>


この段階でアプリにアクセスすると一つだけ小さな問題が発生してしまっています。

それは上記画像のように画面左上のアプリタイトルが白字テキストから下線付きの青字テキストに変更されてしまっていることです。

動作上は問題ありませんがデザイン上いただけませんね。
これは、アンカータグのデフォルトのスタイル設定でレンダリングされた為に起きています。

よって次のスタイルをAppNAvigation.vue の最下部へ追加し矯正しましょう。

<style scoped>
a {
  color: white;
  text-decoration: none;
}
.router-link-exact-active {
  color: white;
  text-decoration: none;
}
.v-toolbar__title {
  color: white;
  text-decoration: none;
}
</style>

お疲れ様です、これで各メニューとページをルーティングし終わりました。

  • MENU
  • SIGN IN
  • JOIN

このそれぞれのボタンをクリックすると適切なページにリダイレクトされるようになりましたね!
最後にAbout.vue についても一貫性を保つため次のように更新しておきましょう。

src/views/About.vue

<template>
  <v-container fluid>
    <v-layout>
      <h1>About Page</h1>
    </v-layout>
  </v-container>
</template>
<script>
export default {
  name: "About"
};
</script>
<style scoped>
</style>


まとめ

今回の投稿では Vue Router を使用して各ページを読み込む方法と、そのファイルの配置について実践していきました。
次回の投稿では、認証にFirebaseを使用する方法について説明します。
またVuexでアプリケーション内の「状態監視」を行っていきましょう。

完成版のソースコードはGitHubにアップロードしてあります

2019-11-23TIPS,Vue.jsFirebase,Vuetify,Vuex

Posted by Kenny