見出し画像

コンポーネント間のデータ受け渡し

今回はコンポーネント間のデータとメソッドの受け渡しや使い方を書いていきます。

1,親から子へ

今回は名前付きで渡す一番ベーシックなやり方でやります。
ちなみにキャメルでもスネークケースでもどちらでも書けます。
先にコードと実際の画面見せます!

parent.vue

<template>
    <div>
      <child message='child' />
    </div>
</template>

<script lang="ts">
  import child  from './child.vue'
  
  export default ({
    components: { child },
  })
</script>

child.vue

<template>
  <div>
    <a>{{message}}</a>
  </div>
</template>

<script lang="ts">
  export default ({
    props:{
      message:{
        type: String,
        required:true,
      }
    }
  })
</script>

こんな感じです。
今回はparent(親)とchild(子)で分けてます。
まず、子でpopsに受け取る名前などを設定します。
親はその名前宛てにデータを送ります。
以上、簡単ですね。

2,子から親へ

こっちではmountedとか使ってますが、Vueのライフサイクルで調べてもらえばわかると思います。一応公式リンク↓

これも先にコード見せます。

parent.vue

<template>
    <div>
      {{message}}
      <child @parentMethod="updateMessage" />
    </div>
</template>

<script lang="ts">
  import child  from './child.vue'
  
  export default ({
    components: { child },
    data() {
      return {
        message:''
      }
    },
    methods: {
      updateMessage(message) {
        this.message = message
      }
    }
  })
</script>

child.vue

<template>
  <div>
  </div>
</template>

<script lang="ts">
  export default ({
    data() {
      return {
        message: 'child->parent'
      }
    },
    mounted() {
      this.$emit('parentMethod',this.message)
    }
  })
</script>

やってることは単純ですが、今回の実装では、前述したようにライフサイクルの知識が若干必要になります。
$emitを使って親へ送ります。
今回はparentMethodというキーを割り当ててメッセージを送ることにします。
呼び出し側は@parentMethodで呼び出し。
あとは用意しておいた代入メソッドを呼び出して終わりです。

3,子から親のメソッドを発火する

次はメソッドの発火です。
この辺はあまり前と変わらないです。
では、サンプルコードです。

parent.vue

<template>
    <div>
      <child @parentEvent="parentEvent" />
    </div>
</template>

<script lang="ts">
  import child  from './child.vue'
  
  export default ({
    components: { child },
    methods: {
      parentEvent() {
        console.log('ボタンが押されました')
      }
    }
  })
</script>

child.vue

<template>
  <div>
    <button @click="childEvent">親のイベント発火</button>
  </div>
</template>

<script lang="ts">
  export default ({
    methods: {
      childEvent() {
        this.$emit('parentEvent')
      }
    }
  })
</script>

今回は子にボタンを持たせて、それを押下することで親のメソッドを呼び出す仕組みにします。
クリックしたときの処理で$emitで名前を付けます。
受け取り側ではその名前を受け取った時に実行される処理を書いておきます。
これだけですね。

4,親から子のメソッドを発火する

とりあえずコードはこちらです。

parent.vue

<template>
    <div>
      <child ref="child" />
      <button @click="parentEvent">子のイベント発火</button>
    </div>
</template>

<script lang="ts">
  import child  from './child.vue'
  
  export default ({
    components: { child },
    methods: {
      parentEvent() {
        this.$refs.child.childEvent()
      }
    }
  })
</script>

child.vue

<template>
  <div>
  </div>
</template>

<script lang="ts">
  export default ({
    methods: {
      childEvent() {
        console.log('ボタンが押されました')
      }
    }
  })
</script>

このような構造はあんまり使わないかもしれないです。
親では子の中身を扱うときにref関数で属性を与えます。
今回はchildという名前で呼び出し時に宣言しました。
親でボタンが押されたときに子のメソッドを呼び出したいので、先ほどのref関数と名前、あとは使いたいメソッドを宣言すれば完了です。

5,まとめ

今回はこのように使い方をまとめてみました。
実際の業務での実装で使う場面があるとしたら、ステータスをbooleanで管理してトグルで切り替えるような場合とかに限定したい感じはありますね。

このような構造が多くなると可読性が落ちてしまう原因になります。
また共通で使っていたような場合、修正がややこしくなりバグの温床になってしまうかもしれません。

なので、どうしてもという場合を除いて、極力使わないというのがベターな気がします。