LoginSignup
0

More than 3 years have passed since last update.

TypeScript+Vue の環境で動的コンポーネント

Last updated at Posted at 2019-06-27

概要

Vue + TypeScript の環境で v-bind:is による動的コンポーネントの扱い方について調べたところ、あまり情報が見つからなかったので、色々試して 2パターンの解決法を見つけたのでメモ。

動的コンポーネントについてはこちら:コンポーネントの基本 — Vue.js

開発環境

TypeScript (3.4.3)
Vue (2.6.10)

(カッコ内は記事を書いている時のバージョン)

JavaScript での例

<template>
  <div>
    <ul class="tabs">
      <li @click="changeChild('hoge')">Hoge</li>
      <li @click="changeChild('fuga')">Fuga</li>
    </ul>
    <component :is="currentChild" />
  </div>
</template>

<script>
import HogeHoge from "HogeHoge.vue";
import FugaFuga from "FugaFuga.vue";

export default {
  data: function(){
    return {
      currentChild: HogeHoge
    };
  },
  components: {
    HogeHoge,
    FugaFuga
  },
  methods: {
    changeChild(name) {
      this.currentChild = name === "hoge" ? HogeHoge : FugaFuga;
    }
  }
};
</script>

TypeScript の場合

方法その 1: バインドする変数の型を any にする。

<template>
  <div>
    <ul class="tabs">
      <li @click="changeChild('hoge')">Hoge</li>
      <li @click="changeChild('fuga')">Fuga</li>
    </ul>
    <component :is="currentChild" />
  </div>
</template>

<script lang="ts">
  import HogeHoge from "HogeHoge.vue";
  import FugaFuga from "FugaFuga.vue";
  import { Component, Vue } from "vue-property-decorator";

  @Component({
    components: {
      HogeHoge,
      FugaFuga
    }
  })
  export default class OurParent extends Vue {
    currentChild: any = HogeHoge;

    changeChild(name) {
      this.currentChild = name === "hoge" ? HogeHoge : FugaFuga;
    }
  }
</script>

こうすると JavaScript と同じように import してきたコンポーネントをそのまま突っ込めますが、any に逃げる形になってしまいます。

方法その 2: バインドする変数の型を string にして、コンポーネント名で指定。

<template>
  <div>
    <ul class="tabs">
      <li @click="changeChild('hoge-hoge')">Hoge</li>
      <li @click="changeChild('fuga-fuga')">Fuga</li>
    </ul>
    <component :is="currentChild" />
  </div>
</template>

<script lang="ts">
  import HogeHoge from "HogeHoge.vue";
  import FugaFuga from "FugaFuga.vue";
  import { Component, Vue } from "vue-property-decorator";

  @Component({
    components: {
      HogeHoge,
      FugaFuga
    }
  })
  export default class OurParent extends Vue {
    currentChild: string = "hoge-hoge";

    changeChild(name) {
      this.currentChild = name;
    }
  }
</script>

個人的にはこちらの方がインスペクター上で判別のしやすく、JavaScript での対応方法としても挙げられているので、良いと思います。

(こっちの方法は、最初 components に子コンポーネントを登録し忘れて若干詰まった、という話もあったりなかったりします。)

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
What you can do with signing up
0