【Vue.js】セレクトボックスで選択した要素に連動してコンテンツを切り替える方法

ゆーたろー

こんにちは、ゆーたろーです。

大阪のHRTechベンチャーのエンジニアです。
TypeScript/Vue.js(Nuxt.js)/Laravelを使っています。

・プログラミングスクール講師
・月1で勉強会運営
・Twitter(フォロワー4700人以上)で情報発信

など色々やっている1児のパパです。

この記事ではJavaScriptのフレームワークであるVue.jsを使って、

セレクトボックスで選択した項目に連動して入力フォーム等のコンテンツを切り替える

という機能を実装します。

目次

参考教材・技術書

僕はVue.jsの学習にはこちらの教材と技術書を使っています。

【超オススメ】超Vue.js 2 完全パック (Vue Router, Vuex含む)

Vue.jsの基礎〜応用まで網羅できるうえ、Vue RouterVuexAxiosなどVue.jsでのフロントエンド開発には欠かせないパッケージについても学習できるのでVue.jsを勉強したい全ての人にオススメです。

Vue.js&Nuxt.js超入門

Laravel青本/緑本で超お馴染みの掌田津耶乃さんの入門書です。Vue.jsだけでなくNuxt.js(Vue.jsのフレームワーク)の基礎をしっかり抑えたい方にオススメです。(僕はNuxt.js学習用に購入しました)

使うVue.jsの機能

セレクトボックスで選択した項目に連動して入力フォームを切り替えるを実装するために使用するVue.jsの機能はこちらです。

  • v-forディレクティブ
  • v-if ディレクティブ
  • v-bindディレクティブ
  • v-modelディレクティブ
  • dataプロパティ
  • computedプロパティ

というわけで解説していきますね!

実装手順

使用した便利ツール『CodeSandbox』

この記事ではWebエディター(環境構築不要でブラウザ上で簡単にコードを書ける)のCodeSandboxを使用しています。

このツールを使えばVue.jsのコードのプログラミングに集中できるのでちょっと試したい時とかにとても重宝します。

こういうちょっとしたアウトプットには環境構築不要でとても楽。

この記事でもVueコンポーネントの解説のみとします。

完成形

下画像のようにテキストボックスの選択項目を変えることによりその下に表示されるコンテンツを切り替えます。

完成形のコード

この記事で実装する機能の完成形のコードがこちらです。

<template>
  <div id="app">
    <select v-model="selectedItem">
      <option 
        v-for="item in selectItems" 
        :value="item.id" 
        :key="item.id"
      >
        {{ item.label }}
      </option>
    </select>
    <div v-if="isText">
      <input type="text" placeholder="テキストフォーム" />
    </div>
    <div v-if="isTextArea">
      <textarea cols="30" rows="10" placeholder="テキストエリア"></textarea>
    </div>
    <div v-if="isButton">
      <button>ボタン</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      selectItems: [
        { id: 1, label: "テキストフォーム" },
        { id: 2, label: "テキストエリア" },
        { id: 3, label: "ボタン" },
      ],
      selectedItem: 1,
    };
  },
  computed: {
    isText() {
      return this.selectedItem === 1;
    },
    isTextArea() {
      return this.selectedItem === 2;
    },
    isButton() {
      return this.selectedItem === 3;
    },
  },
};
</script>

手順を分けて解説していきます。

セレクトボックスを作成する(v-for、v-bind、data)

まずはテキストボックスを作成します。

Vueコンポートのテンプレートにセレクトボックスの要素(optionタグ)を直接書いてもいいのですが、せっかくVue.jsを使うのでv-forディレクティブを使用しています。

そのためには先にdataプロパティにselectItemsというdataでセレクトボックスの要素を定義します。上記コードのこの部分です。

<script>
export default {
  name: "App",
  data() {
    return {
      // セレクトボックスの要素(optionタグ)のデータを定義
      selectItems: [
        { id: 1, label: "テキストフォーム" },
        { id: 2, label: "テキストエリア" },
        { id: 3, label: "ボタン" },
      ],
    };
  },
};
</script>

各要素のオブジェクトにidlabelというプロパティを持たせて配列で定義しています。

それではv-forディレクティブを使ってセレクトボックスを作ります。

<template>
  <div id="app">
    <select>
      // v-forディレクティブ
      <option 
        v-for="item in selectItems" 
        :value="item.id" 
        :key="item.id"
      >
        {{ item.label }}
      </option>
    </select>
  </div>
</template>

v-forディレクティブの使い方をまとめます。

  • HTMLタグの属性にv-for="要素(命名は自由) in 定義した配列"を定義する
  • :value=””でvalue属性を設定する
  • :key=””で各要素を一意に識別するためのkey属性を設定する

dataプロパティで定義したselectItemsの各要素をitemという変数に繰り返し格納しています。item1つ1つはオブジェクトなのでプロパティにアクセスする時はオブジェクト名.プロパティ名でアクセスすることができます。

またHTMLタグの属性に動的なプロパティを使う場合はv-bindディレクティブを使います。

正式な書き方はv-bind:属性名="属性値"ですが、v-bindを省略して:属性名="属性値"と書くことができます。

選択中の要素を取得

今回の使用中はセレクトボックスで選んだ要素に連動して処理を行いたいので、現在選択している要素はどれか?と取得する必要があります。

そのためにはVue.jsのとても便利な機能である双方向データバインディングを使います。
双方向データバインディングはv-modelディレクティブを使うことで簡単に実装できます。

<template>
  <div id="app">
    // v-modelで双方向データバインディング
    <select v-model="selectedItem">
      <option 
        v-for="item in selectItems" 
        :value="item.id" 
        :key="item.id"
      >
        {{ item.label }}
      </option>
    </select>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      selectItems: [
        { id: 1, label: "テキストフォーム" },
        { id: 2, label: "テキストエリア" },
        { id: 3, label: "ボタン" },
      ],
      // 選択中の要素のid
      selectedItem: 1,
    };
  },
};
</script>

まずはdataプロパティにselectedItemを定義します。(初期値は1)

selectタグにv-model="selectedItem"を設定してあげることでセレクトボックスの要素の選択と連動してselectedItemの値を変えるようにしています。

選択した要素に連動してコンテンツを切り替える

最後の手順です。

v-ifディレクティブを使ってセレクトボックスで選択した要素によってフォームやボタンを切り替えます。

<template>
  <div id="app">
    <select v-model="selectedItem">
      <option 
        v-for="item in selectItems" 
        :value="item.id" 
        :key="item.id"
      >
        {{ item.label }}
      </option>
    </select>
    // セレクトボックスで「テキストフォーム」を選択した場合にのみ表示
    <div v-if="isText">
      <input type="text" placeholder="テキストフォーム" />
    </div>
    // セレクトボックスで「テキストエリア」を選択した場合にのみ表示
    <div v-if="isTextArea">
      <textarea cols="30" rows="10" placeholder="テキストエリア"></textarea>
    </div>
    // セレクトボックスで「ボタン」を選択した場合にのみ表示
    <div v-if="isButton">
      <button>ボタン</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      selectItems: [
        { id: 1, label: "テキストフォーム" },
        { id: 2, label: "テキストエリア" },
        { id: 3, label: "ボタン" },
      ],
      selectedItem: 1,
    };
  },
  // 今何が選ばれているかを判定する算出プロパティ
  computed: {
    isText() {
      return this.selectedItem === 1;
    },
    isTextArea() {
      return this.selectedItem === 2;
    },
    isButton() {
      return this.selectedItem === 3;
    },
  },
};
</script>

まずはisTextisTextAreaisButtonという3つのcomputed(算出)プロパティを定義します。

行っている処理は簡単でdataプロパティで定義したselectedItemと各要素のidを比較して同じだったらtrue、違っていたらfalseを返しています。
(ここ、マジックナンバーになっていますが今回はこのまま行きます)

Vueテンプレート内でこれらの算出プロパティ使ってv-ifディレクティブで各コンテンツの切り替えを行います。

v-ifディレクティブの使い方は以下の通りです。

<div v-if="isText">
  // isTextがtrueだったら表示するコンテンツ
</div>

テキストエリア、ボタンのところも同様に設定しています。

v-ifディレクティブに似たv-showディレクティブがありますが、この違いの説明はこの記事では割愛します。

以上の手順で実装することで

セレクトボックスで選択した項目に連動して入力フォーム等のコンテンツを切り替える

を実装することができます。

ぜひCodeSandboxやご自身のローカル環境で試してみてください。

最後に

この記事ではVue.jsの基礎的な内容を実例を用いて実装・解説しました。

やはり小さなものでも実際に作ってみた方が習得は早いと感じています。

プログラミングはアウトプット重視の方が身につきます。

今後も技術記事を投稿していくのでぜひ読んでいただけると嬉しいです。

オススメ教材

個人的には1つ目のUdemyの講座が超オススメ。

“頭おかしい”プログラミングスクール『やんばるエキスパート』

内定者続出のエンジニア転職特化オンラインコミュニティ『転職クエスト』

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

この記事を書いた人

上場グループのHRTechベンチャーで働くWebエンジニアです。
新卒で入社した大手重工メーカを4年で退職し、2020年4月からエンジニアとキャリアチェンジしました。

仕事ではTypeScript/Vue.js(Nuxt.js)/Laravelを主に使っています。

プログラミングスクールの講師やデザイン関連のお仕事もさせてもらっています。

神戸で「つながる勉強会」という勉強会を月1で運営しています。
https://tsunagaru-kobe.connpass.com/

お仕事のご依頼、ご相談はお問い合わせページもしくはTwitterのDMからお願いします。

コメント

コメントする

目次
閉じる