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?

【Vue2系・Vue3系】親子間のデータの受け渡しの違い(sync・emit・emits)

Posted at

はじめに

直近で自作のアプリケーションをVUe2系からVue3系にリライトしたため、その時の操作を備忘録として残します。
今回は親子間の受け渡しの違いについてまとめていきます。

環境

項目 Vue2 Vue3
Vueのバージョン 2.6.14 3.5.13

Vue2

①親コンポーネントにsyncした上で、子コンポーネントでemitを発火することで受け渡し可能
②プロパティを更新したい場合はupdate:.syncで指定したプロパティ名を設定
③子から親のファンクションを発火したい場合は、@で指定したメソッドを指定

ParentComponent.vue(vue2)
<template>
    <div>
        <child-component
            :update-data.sync="updateData"
            @updateProcessing = "updateFunction"/>
        <p> {{ updateData }} </p>
        <p> {{ emitData }} </p>
    </div>
</template>

<script>
    import ChildComponent from "ChildComponentまでのパス";

    export default {
        components: {
            ChildComponent
        },
        data() {
            return {
                updateData: '親の値',
                emitData: ''
            }
        },
        methods: {
            updateFunction(argument){
                // 子から渡ってきた値を代入
                this.emitData = argument
            }
        }
    }
</script>

ChildComponent.vue(vue2)
<template>    
    <div>
        <button @click="update"> 親の値が変わるボタン </button>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                childData: '子の値',
                emitChildData: '子から値が渡ってきたよ!'
            }
        },
        methods: {
            update(){
                // 親のプロパティを更新
                this.$emit('update:updateData', this.childData)
                // 親のコンポーネントにあるupdateFunctionメソッドを発火
                this.$emit('updateProcessing',this.emitChildData)
            }
        }
    }
</script>

押下前
image.png

押下後
image.png

Vue3

①親コンポーネントに v-modal:プロパティ名 した上で、子コンポーネントでemitを設定することで受け渡し可能(v-modelは複数指定可能)。
②子コンポーネントでemitsの指定が必要
②プロパティを更新したい場合はupdate:v-modelで指定したプロパティ名を設定
③子から親のファンクションを発火したい場合は、@で指定したメソッドを指定

ParentComponent.vue(vue3)
<template>
    <div>
        <child-component
+           v-model:update-data="updateData"
+           v-model:update-data2="updateData2"
            @updateProcessing = "updateFunction"/>
        <p> {{ updateData }} </p>
        <p> {{ updateData2 }} </p>
        <p> {{ emitData }} </p>
    </div>
</template>

<script>
    import ChildComponent from "子コンポーネントまでのパス";

    export default {
        components: {
            ChildComponent
        },
        data() {
            return {
                updateData: '親の値',
                updateData2: '親の値2',
                emitData: ''
            }
        },
        methods: {
            updateFunction(argument){
                this.emitData = argument
            }
        }
    }
</script>

ChildComponent.vue(vue3)
<template>
    <div>
        <button @click="update">親の値が変わるボタン </button>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                childData: '子の値',
                childData2: '子の値2',
                emitChildData: '子から値が渡ってきたよ!'
            }
        },
+       emits: ['update:updateData', 'update:updateData2', 'updateProcessing'],
        methods: {
            update(){
                // 親のプロパティを更新
                this.$emit('update:updateData', this.childData)
                this.$emit('update:updateData2', this.childData2)
                // 親のコンポーネントにあるupdateFunctionメソッドを発火
                this.$emit('updateProcessing',this.emitChildData)
            }
        }
    }
</script>

押下前(vuetifyのデザインテンプレートを使用)
image.png

押下後
image.png

ちなみにvue2と同じくsyncを使おうとするとbuildの時にエラーが出ます。

image.png

また一部emitsにデータを登録し漏れるとconsoleにwarningが出力されます。(下記はupdate:updateDataのみemitsに登録した場合)

image.png

さいごに

アップデート時に親子間のデータ受け渡しに苦労したため、まとめてみました。
迷っている方の力になれば幸いです。

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?