1
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.

【Nuxt】グローバルメニュー に下タブを出す。レスポンシブ対応

Posted at

はじめに

グローバルメニューにホバーした時やクリックしたときにしたタブを出して、ページ誘導を試みる実装をしていて少し詰まったので記事として共有してみます。
Nuxt(Vue)で本記事のような内容は見受けられなかったので、皆さんのお役に立てれば幸いです。
また、本記事はVuetifyを使用しています。
では、さっそく内容に迫っていきましょう。

最終イメージ【グローバルメニュー】

下記画像が本記事のグローバルメニューの最終イメージです。
スクリーンショット 2021-02-11 9.11.30.png

スタート【グローバルメニュー】

まずはVuetifyのAppBar部分をいじっていきます。

<v-app-bar
      v-scroll="onScroll"
      app
      dark
      elevate-on-scroll
    >
      <v-img
        v-if="isScrolling || $route.name!=='index'"
        class="shrink"
        max-width="60%"
        width="65"
        src="/home.png"
        @click="$router.push('/')"
      />
      <v-spacer />
      <v-toolbar-items v-if="$vuetify.breakpoint.mdAndUp">
        <template v-for="item in items">
          <v-btn
            v-if="!item.math"
            :key="item.id"
            :active-class="!isScrolling && $route.name==='index' ? 'primary--text' : undefined"
            :to="item.to"
            text
            v-text="item.text"
          />
          <v-menu
            v-else
            :key="item.id"
            bottom
            offset-y
            :open-on-hover="true"
            :open-on-click="false"
          >
            <template v-slot:activator="{on}">
              <v-btn text v-on="on">
                <span>{{ item.text }}</span>
                <v-icon>mdi-menu-down</v-icon>
              </v-btn>
            </template>
            <v-list>
              <template v-for="(math,i) in item.math">
                <v-divider v-if="math.divider" :key="i" />
                <v-list-item v-else :key="math.id" :to="math.to">
                  <v-list-item-title :style="'font-size:0.9rem'" class="mr-2">
                    {{ math.title }}
                  </v-list-item-title>
                  <v-icon
                    :color="math.color"
                    size="26"
                    v-text="math.icon"
                  />
                </v-list-item>
              </template>
            </v-list>
          </v-menu>
        </template>
      </v-toolbar-items>
      <v-app-bar-nav-icon
        v-else
        aria-label="Open Navigation Drawer"
        @click="toggleDrawer"
      />
    </v-app-bar>
export default {
  data: () => ({
    isScrolling: false,
    hoverFlag: false,
    items: [
      {
        to: '/',
        text: '国語'
      },
      {
        text: '数学',
        math: [
          {
            title: '数IA',
            icon: 'mdi-chevron-right',
            color: 'primary',
            to: '/math/math_one-a'
          },
          { divider: true, inset: true },
          {
            title: '数ⅡB',
            icon: 'mdi-chevron-right',
            color: 'primary',
            to: '/math/math_two_b'
          },
          { divider: true, inset: true },
          {
            title: '数ⅢC',
            icon: 'mdi-chevron-right',
            color: 'primary',
            to: '/math/math_three_c'
          }
        ]
      },
      {
        to: '/english',
        text: '英語'
      },
      {
        to: '/society',
        text: '社会'
      }
    ]
  })
  methods: {
    onScroll () {
      this.isScrolling = (window.pageYOffset ||
        document.documentElement.scrollTop || 0) > 25
    }
  }
}

* storeを利用している部分は省略して記載しております。

最終イメージ【レスポンシブ】

下記画像が本記事のドロワーメニューの最終イメージです。
スクリーンショット 2021-02-11 11.55.03.png

スタート【ドロワーメニュー】

まずはVuetifyのv-navigation-drawer部分をいじっていきます。

<v-navigation-drawer
    v-model="inputValue"
    fixed
    right
    temporary
  >
    <v-row
      align="center"
      class="ma-0 pa-3 flex-no-wrap"
    >
      <v-spacer />
      <v-btn
        aria-label="Close"
        class="ml-4"
        icon
        @click="toggleDrawer"
      >
        <v-icon>mdi-close</v-icon>
      </v-btn>
    </v-row>
    <v-divider />
    <v-list>
      <template v-for="item in items">
        <v-list-item
          v-if="!item.lists"
          :key="item.id"
          :to="item.to"
          @click="menuClose"
        >
          <v-list-item-content>
            <v-list-item-title>
              {{ item.text }}
            </v-list-item-title>
          </v-list-item-content>
        </v-list-item>
        <v-list-group
          v-else
          :key="item.id"
          v-model="item.active"
        >
          <template v-slot:activator>
            <v-list-item-content>
              <v-list-item-title>
                {{ item.text }}
              </v-list-item-title>
            </v-list-item-content>
          </template>
          <v-list-item
            v-for="(math,i) in item.lists"
            :key="i"
            :to="math.to"
          >
            <v-list-item-title class="ml-6">
              <v-icon :color="math.color" class="mr-3" v-text="math.icon" />
              {{ math.name }}
            </v-list-item-title>
          </v-list-item>
        </v-list-group>
      </template>
    </v-list>
  </v-navigation-drawer>
export default {
  data: () => ({
    items: [
      {
        to: '/',
        text: '国語'
      },
      {
        text: '数学',
        active: false,
        lists: [{
          name: '数IA',
          to: '/math/math_one_a',
          icon: 'mdi-chevron-right',
          color: 'primary'
        },
        {
          name: '数ⅡB',
          to: '/math/math_two_b',
          icon: 'mdi-chevron-right',
          color: 'primary'
        },
        {
          name: '数ⅢC',
          to: '/math/math_three_c',
          icon: 'mdi-chevron-right',
          color: 'primary'
        }
        ]
      },
      {
        to: '/english',
        text: '英語'
      },
      {
        to: '/society',
        text: '社会'
      }
    ]
  }),

  computed: {
    inputValue: {
      get () {
        return this.drawer
      },
      set (val) {
        this.setDrawer(val)
      }
    }
  },

  methods: {
    menuClose () {
      this.items.forEach((item) => { item.active = false })
    }
  }
}

* storeを利用している部分は省略して記載しております。

おわりに

下タブ(詳細URL)を使うときはV-ifでの条件分岐によって、上手く実装することがポイントでした。
具体的にはv-list-itemとv-list-groupを分ける。v-list-groupで一つにまとめると挙動が異なるので注意しなければいけませんでした。
少しでもお役手に立てればLGTMをお願い致します🙇‍♂️

1
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
1
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?