0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

QR忘れ物アプリ (3) メニュー [Vue,Vuetify,Firebase]

Posted at

はじめに

構成

  1. 環境構築: https://qiita.com/rayan/items/5d04ee2ca7860c220dec
  2. ログインページ: https://qiita.com/rayan/items/1f0576395b9727635461
  3. メニュー: 今回

GitHubリポジトリ

準備中

操作するファイル

  • src
    • components
      • Drawer.js
      • Header.js
    • router
      • index.js
    • views
      • MainMenu.vue

src/components/Drawer.vue

ナビゲーションメニュー。いくつかのビューで共通する要素のため、componentsの中に入っている。

  • Drawer.vue内ではshowというpropを定義しています。これはDrawer要素の表示の有無を示している。
  • ナビゲーションメニュー表示後、閉じた場合にはshow=falseになる。この変化を親コンポーネントであるHeaderのshowに適用するために以下の処理を行う。
    • showの変化(true->false, false->true)をwatchで検出。
    • this.$emit('update:show', this.show)を行う。
      • これは(true->false, false->true)の両方で発火するため、this.$emit('update:show', false)にするとDrawerが開かなくなる。
    • 親であるHeaderに:show.sync="show"がある。これは以下の二つの役割を担っている。
      • :show="show"ではpropであるshow(左)にshow(右)の値を代入
      • v-on:update:show="show = $event"では子のupdate:showイベントを受けて親のshow(右)の値を更新
<template>
  <v-navigation-drawer
    v-model="show"
    absolute
    temporary
  >
    <v-list>
      <v-list-item-group
        v-model="selectedItem"
        color="primary"
      >
        <v-list-item
          v-for="(item, i) in items"
          :key="i"
          :to="item.link"
        >
          <v-list-item-icon>
            <v-icon v-text="item.icon"></v-icon>
          </v-list-item-icon>
            <v-list-item-content>
          <v-list-item-title v-text="item.text"></v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list-item-group>
    </v-list>
  </v-navigation-drawer>
</template>

<script>
export default {
  name: "Drawer",
  components: {
    //
  },
  props: {
    show: {
      type: Boolean,
      default: false
    }
  },
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Preferences', icon: 'mdi-account-cog', link: '/userPreferences'},
      { text: 'Item Registeration', icon: 'mdi-tag-plus' , link: '/itemRegisteration'},
      { text: 'Item List', icon: 'mdi-tag-multiple', link: '/itemList'},
    ]
  }),
  watch: {
    show() {
      this.$emit('update:show', this.show);
    }
  },
};
</script>

src/components/Header.vue

ヘッダー要素。いくつかのビューで共通する要素のため、componentsの中に入っている。

  • v-app-bar-nav-iconをクリックすることによって、propsを用いてインポートしたDrawerを表示している。
    • 表示していない状態(show=false)から表示する状態(show=true)に変化させる。
  • Header.vue内ではtitleというpropを定義している。これはHeader要素で表示する文字列を示している。
<template>
  <div>
    <v-card
      class="mx-auto"
      tile
    >
      <v-toolbar>
        <v-app-bar-nav-icon @click.stop="show = !show"></v-app-bar-nav-icon>
        <v-toolbar-title>{{title}}</v-toolbar-title>
      </v-toolbar>
    </v-card>
    <Drawer :show="show" v-on:update:show="show = $event"/>
  </div>
</template>

<script>
import Drawer from '@/components/Drawer'

export default {
  name: "Header",
  components: {
    Drawer
  },
  data: () => ({
    show: false
  }),
  props: {
    title: String,
  },
};
</script>

src/views/MainMenu.vue

メインメニューの要素。

  • props
    • <Header :title="title"/>によってHeaderのpropであるtitle(左)の値をtitle(右)の値に設定する。
<template>
  <div>
    <Header :title="title"/>
  </div>
</template>

<script>
import Header from '@/components/Header'

export default {
  name: "MainMenu",
  components: {
    Header
  },
  data: () => ({
    title: 'Main Menu'
  }),
};
</script>

router/index.js

新しくつくったMainMenuページの情報を追加する。

import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

const routes = [
  {
    path: "*",
    redirect: "/"
  },
  {
    path: "/mainMenu",
    name: "MainMenu",
    meta: { requiresAuth: true },
    component: () =>
      import("@/views/MainMenu.vue"),
  },
  {
    path: "/",
    name: "Authentication",
    component: () =>
      import("@/views/Authentication.vue"),
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

router.beforeEach((to, from, next) => {
  let requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  let currentUser = firebase.auth().currentUser
  if (requiresAuth) { // if this page requires auth, redirect to auth page
    if (!currentUser) {
      next({
        path: '/',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // this is required
  }
})

export default router;

Build

  • ビルドし、動作をテストする。動作のテストにはFirebase Emulatorが必要であるため、起動する。
npm run build
firebase emulators:start
  • dist/index.htmlをブラウザで閲覧する。ログイン後、移動するMainMenuページに移動する。
    • mainmenu.PNG
  • 左上の3本線のアイコンをクリックすると下の画像のようになることを確認する。
    • drawer.PNG

次回

ユーザー設定確認・変更ページ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?