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 5 years have passed since last update.

【Nuxt.js】タブ切り替えを実装する

0
Last updated at Posted at 2021-05-25

■目的

勉強のためNuxt.jsのサンプル集を作る

目標2

タブ切り替えを実装する

ざっくり仕様

  • タブのボタン部分もコンテンツ部分も配列から読み込む
  • コンテンツ部分にはHTMLを自由に記述できるようにする
  • PCではタブ、スマホではアコーディオンといったように、表示を切り替えたい

default.vue

ベースファイルはここで書いたものと同じ。
components/template/TabsMenu.vue内で処理をしていく。

TabsMenu

まずはボタン部分のコンポネントを用意する。これ、moleculesに格納したけど、
どう考えてもatomsだった……。

components/molecules/etc/TabsMenu.vue
<template>
  <span>
    {{ tabMenuName }}
  </span>
</template>

<script>
export default {
  props: {
    tabMenuName: {
      type: String,
      default: ''
    }
  }
}
</script>

親コンポネントからボタン内のテキストをpropsで受け取って表示する。

TabsContent

これもatomsだった。南無三。

components/molecules/etc/TabsContent.vue
<template>
  <div class="c-tab_content--block-inner">
    <div v-html="tabContentText" />
  </div>
</template>

<script>
export default {
  props: {
    tabContentText: {
      type: String,
      default: ''
    }
  }
}
</script>

コンテンツ内に自由にHTMLを記述できるようにv-htmlを採用した。
別に誰かに編集させるわけではないし、ここではいったんこれでOKとした。

TabsMenu(親コンポネント)

ここで、上記2つの子コンポネントを読み込む。

components/templates/Tabsmenu.vue
<template>
  <main>
    <section id="p-tabs-menu_box02">
      <div class="c-box">
        <div class="c-tab">
          <ul class="c-tab_menu">
            <li v-for="(tab, index) in tabs" :key="tab.tabId" class="c-tab_menu--item" :class="[ activetab === (index + 1) ? 'active' : '', tab.tabClass ]" @click="activetab = (index + 1)">
              <MoleculesEtcTabsMenu
                :tab-menu-name="tab.tabName"
              />
            </li>
          </ul>
          <div class="c-tab_content">
            <div v-for="(item, index) in contents" :key="item.itemId" class="c-tab_content--block" :class="[ activetab === (index + 1) ? 'show' : '' ]">
              <div v-show="activetab === (index + 1)">
                <MoleculesEtcTabsContent
                  :tab-content-text="item.text"
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    </section><!-- /box02 -->
  </main>
</template>

<script>
export default {
  data () {
    return {
      activetab: 1,
      tabs: [
        { tabId: '1', tabClass: 'c-tab_menu--item01-01', tabName: 'タブ01' },
        { tabId: '2', tabClass: 'c-tab_menu--item01-02', tabName: 'タブ01タブ02' },
        { tabId: '3', tabClass: 'c-tab_menu--item01-03', tabName: 'タブ01-03' }
      ],
      contents: [
        {
          itemId: '1',
          text: '<p>タブの中のテキストは何が入るかわからないから、複数行になっても見た目を整えるcssを書く。</p>' +
                '<p>ただデザインにもよると思うけれど、スマホでもタブを採用する場合、タブ自体の数は気をつけないといけない。</p>' +
                '<p>このデザインだと、タブが4つになることは想定していない</p>'
        },
        {
          itemId: '2',
          text: '<p><img src="/images/sample/tabs-menu.jpg" alt="タブメニューイメージ"></p>' +
                '<p>コンテンツ内ではv-htmlを採用しているので、<strong>自由にHTMLを書くことができる。</strong></p>' +
                'v-htmlはXSSの危険性があるが、あくまで実装側のみの話であれば<span style="color: red">そこまでクリティカルではないのでは?</span>'
        },
        {
          itemId: '3',
          text: '<p>とりあえずコピペで動かしてみた。</p>' +
                '<p>jQueryだともう少し複雑になる。Vue.js優秀だなと痛感。</p>'
        }
      ],
    }
  }
}
</script>
※cssは省略

ボタンとコンテンツ部分のHTMLを完全に分けているので楽。
配列の数を取得。数がイコールになるものを判定して
表示と非表示を切り替えている。

結果

うん、動いた。と、素直に喜びたいところなのだけど、実は激しく苦戦して、
今回のコードは下記を参考に多少自分なりにアレンジしたに過ぎない。

シンプルでわかりやすかった。
次はコンポネントを分けないでタブ切り替えを実装した。

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?