owned mediaウェブ制作に役立つコンテンツを発信中!

Vue.jsでcomponent要素とis属性を使って呼び出すコンポーネントを動的に切り替える

最終更新日: Update!!
Vue.jsでコンポーネントを扱う場合、特定のイベントや条件によって動的に呼び出すコンポーネントを切り替えたい場合があります。そんな場合には「component」と「is」属性を使うことで、コンポーネント名を変数として扱えるようになることで、動的に呼び出すコンポーネントを切り替えることができます。今回はサンプルコードと合わせて具体的にみていきたいと思います。  
コンポーネント名を変数に格納し、動的にコンポーネントを切り替える
下記のように、ラジオボタンでコンポーネントを切り替える場合を例に見ていきます。(記事内の記述はVue.jsの2系のものになります)ラジオボタンの値に合わせてv-ifなどで条件分岐させることもできますが、ラジオボタンの値にコンポーネント名を入れておくことで、そのままコンポーネントが呼び出されるようにしています。v-modelでフォーム要素の値と変数を同期するようにしておき、computed内のメソッドでラジオボタンの値をコンポーネント名に変換するようにします。
<template>
  <div>
    <label><input v-model="selectedComponent" type="radio" name="components" value="default" checked>default</label>
    <label><input v-model="selectedComponent" type="radio" name="components" value="foo">foo</label>
    <label><input v-model="selectedComponent" type="radio" name="components" value="bar">bar</label>
    <label><input v-model="selectedComponent" type="radio" name="components" value="baz">baz</label>
    <component :is="currentComponentName"></component>
  </div>
</template>

<script>
  import Default from '../components/Default.vue';
  import Foo from '../components/Foo.vue';
  import Bar from '../components/Bar.vue';
  import Baz from '../components/Baz.vue';
  export default {
    components: { Default, Foo, Bar, Baz },
    data() {
      return {
        selectedComponent: 'default'
      }
    },
    computed: {
      currentComponentName() {
        return `${this.selectedComponent.charAt(0).toUpperCase()}${this.selectedComponent.slice(1)}`;
      }
    }
  }
</script>
  テンプレート内では、コンポーネント名の要素で呼び出すのではなく「component」という専用の要素を使います。そしてこちらも専用の属性である「is」の値に先ほど変換したコンポーネント名を入れておきます。これで、ラジオボタンの値が変わるたびにコンポーネント名も変化するため、呼び出されるコンポーネントも切り替えられるようになります。変数の初期値にはデフォルトで表示させたいコンポーネントに対応する値を入れておかないのと初期表示でコンポーネントが呼び出されないので注意しておきましょう。  
動的にコンポーネント切り替える際にデータをキャッシュさせたい
動的に切り替えたコンポーネントでデータを保持していたりすると、コンポーネントが再描画されるため保持していた値がリセットされてしまいます。例えば、下記のようにコンポーネント内でテキストボックスなどのフォーム部品があった場合、この入力値は呼び出されるたびに消えてしまいます。
<template>
  <div>
    <input type="text">
  </div>
</template>

<script>
  export default {
    name: 'Foo'
  }
</script>
  そのようなケースでは、下記のように動的なコンポーネント要素を「keep-alive」で囲むようにします。そうすることで、呼び出したコンポーネントのデータをキャッシュすることができます。これで動的にコンポーネントを切り替えた場合でもデータが消えることがありません。
<template>
  <div>
    <label><input v-model="selectedComponent" type="radio" name="components" value="default" checked>default</label>
    <label><input v-model="selectedComponent" type="radio" name="components" value="foo">foo</label>
    <label><input v-model="selectedComponent" type="radio" name="components" value="bar">bar</label>
    <label><input v-model="selectedComponent" type="radio" name="components" value="baz">baz</label>
    <keep-alive>
      <component :is="currentComponentName"></component>
    </keep-alive>
  </div>
</template>
  コンポーネントで値を保持させたり、動的に切り替えるなどはよくあるケースだと思うので、動的なコンポーネントの扱いについてはぜひ覚えておきたいですね。   (参考にさせて頂いたサイト) Vue.js コンポーネントの基本
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram