プログラミングライフスタイル

「Vue.js」の「コンポーネント間の通信」を学ぶ

「コンポーネント」は少しずつ理解が進んできましたが、「コンポーネント間でのデータの受け渡しはどうすればいいのか?」という疑問が浮かんできました。

「コンポーネント」は「UI部品」と考えると「データの共有」が重要になってくるのではないかと思っています。

今回は「コンポーネント間のデータのやり取り」について学んでいきたいと思います。

「親」から「子」のコンポーネントへデータを渡す方法

前回の「コンポーネント」の学習でも触れましたが、さらにプログラムを作って理解を進めていきたいと思います。

「props」を利用することで、「親」から「子」のコンポーネントへデータを渡すことができました。

「子コンポーネント」に「props」を定義することで、「親コンポーネント」から「子コンポーネント」へデータを渡すことができます。

前回とは異なって「データリスト」を「子コンポーネント」へ渡して「リスト形式」で表示をしてみたいと思います。

プログラムを作ってみると、

<div id="app">
    <parent-comp></parent-comp>
</div>
<script>
    const childComp = {
        props: ['id', 'name', 'price'],
        template: '<li>「{{ name }}」は{{ price }}円です。</li>'
    }
    Vue.component('parent-comp', {
        template: '<ul><child-comp v-for="item in items" v-bind:id="item.id" v-bind:name="item.name" v-bind:price="item.price" :key="item.id"></child-comp></ul>',
        components: {
            'child-comp': childComp
        },
        data: function () {
            return {
                items: [
                    { id: 1, name: '唐揚げ定食', price: 880 },
                    { id: 2, name: '焼肉定食', price: 980 },
                    { id: 3, name: '牛丼', price: 520 },
                    { id: 4, name: 'カツカレー定食', price: 920 },
                    { id: 5, name: 'すき焼き定食', price: 980 },
                ]
            }
        }
    })
    let app = new Vue({
        el: '#app'
    })
</script>

のようになります。このプログラムを実行すると、

→「Vue.jsプログラムの実行(コンポーネントのデータ渡し(親→子))」

のようになります。

「v-for」で繰り返し処理を行っていますが、渡すデータを「v-bind」で1つずつ指定しないといけないため、「渡すデータの種類」が増えると「コードを書く量」も増え、可読性も下がってしまいます。

あと、「for文」のところでも登場しましたが、「:key」を書かないと、「コンソール」に「key」を指定するようメッセージが表示されます。

「子」から「親」のコンポーネントへデータを渡す方法

「子のコンポーネント」から「親のコンポーネント」にデータを渡す場合は、下記のようになります。

<div id="app">
    <parent-comp></parent-comp>
</div>
<script>
    const childComp = {
        props: ['id', 'name', 'price'],
        template: '<li>「{{ name }}」は{{ price }}円です。<button v-on:click="selectItem" v-bind:id=id>購入</button></li>',
        methods: {
        	selectItem: function (e) {
            	this.$emit('clickItem', e.target.id);
        	}
    	}
	}
    Vue.component('parent-comp', {
        template: '<ul><child-comp v-on:clickItem="displayItem" v-for="item in items" v-bind:id="item.id" v-bind:name="item.name" v-bind:price="item.price" :key="item.id"></child-comp></ul>',
        components: {
            'child-comp': childComp
        },
        data: function () {
            return {
                items: [
                    { id: 1, name: '空気清浄機', price: 12980 },
                    { id: 2, name: '加湿器', price: 2980 },
                    { id: 3, name: '扇風機', price: 1980 },
                ]
            }
        },
        methods: {
            displayItem: function (itemId) {
                const itemName = this.items[itemId]['name'] + '(' + this.items[itemId]['price'] + '円)';
                alert(`${itemName}が選択されました。`);
            }
        }
    })
    let app = new Vue({
        el: '#app'
    })
</script>

のようになります。このプログラムを実行すると、

→「Vue.jsプログラムの実行(コンポーネントのデータ渡し(子→親))」

のようになります。

仕組みが複雑なので図を作成してみると、

コンポーネントのデータ渡し(子→親)

のようになります。

まず「子コンポーネントのボタン」がクリックされると、「selectItemメソッド」が実行されます。

「子コンポーネント」は、

<button v-on:click="selectItem" v-bind:id=id>購入</button>

のように、「v-on」によって「クリック」されると「子コンポーネント」の「selectItemメソッド」が実行されるよう設定しています。

「selectItemメソッド」では、

selectItem: function (e) {
	this.$emit('clickItem', e.target.id);
}

のように「$emit」が実行されます。

「$emit」は「子コンポーネント」の「ボタンクリック」などのイベントを「親コンポーネント」に伝達することができます。

「第二引数」に「親コンポーネントに渡したい値」を設定すると「親コンポーネント」に値を渡すこともできます。

「親要素」の「template」では、

<child-comp v-on:clickItem="displayItem" v-for="item in items" v-bind:id="item.id" v-bind:name="item.name" v-bind:price="item.price" :key="item.id"></child-comp>

のように「$emit」によって送られた「子コンポーネント」の「clickItem」を検知すると「親コンポーネント」の「displayItemメソッド」を実行するように設定しています。

そして「displayItemメソッド」の「商品情報を表示する処理」が実行されます。

今回は「コンポーネント間の値の渡し方」について学んでいきましたが、プログラムを書いていて「かなり複雑な仕組み」だと感じたので、繰り返しプログラムを書いていかないと忘れてしまいそうです。

難しさを感じる仕組みですが、繰り返し学びながら少しずつ理解していきたいと思います。

→(前へ)「Vue.js」の「コンポーネント」の仕組みを学ぶ

→(次へ)「Vue.js」の「スロット」を学ぶ

HOMEへ