■ はじめに
親・子コンポーネントのデータの受け渡しなどをメモ。
目次
【1】親から子へのアクセス 1)データを渡す ... Prop 2)メソッドを実行する ... ref属性 【2】子から親へのアクセス 1)データを渡す ... parent属性 2)メソッドを実行する ... emit属性 【3】サンプル
【1】親から子へのアクセス
親コンポーネントから子コンポーネントへ データの受け渡しや子のメソッドを実行する際の方法を示す
1)データを渡す ... Prop
Prop
* データを渡す際の子コンポーネントのプロパティに「@Prop()」を付ける
イメージ
<!-- 親 --> <Dialog ref="dialog" title="Title" message="HelloWorld"> <!-- 子 --> import { Component, Prop, Vue } from 'vue-property-decorator'; @Component export default class Dialog extends Vue { @Prop() title!: string; @Prop() message!: string;
2)メソッドを実行する ... ref属性
ref属性
* 子コンポーネントを操作するために、参照IDを割り当てる
$refs
* 子コンポーネント内の要素/メソッドを直接参照できる
イメージ
<template> // ... <!-- 子コンポーネントにchildという参照IDを割り当てる --> <ChildComponent ref="child"/> // ... </template> // ... <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import ChildComponent from '@/components/ChildComponent.vue'; @Component({ components: { ChildComponent, }, }) export default class Parent extends Vue { public sayHello() { // 子コンポーネントのメソッドhelloWorld()を実行する this.$refs.child.helloWorld(); } </script>
【2】子から親へのアクセス
1)データを渡す ... parent属性
* 子から親のデータを取得する際に 「this.$parent.$data.【親コンポーネントのプロパティ】」で取得できる
イメージ
// 子から親のデータを取得 const parentValue = this.$parent.$data.【親コンポーネントのプロパティ】; // 階層が深くなった場合、$parent を増やせばアクセスできる // this.$parent.$parent...
2)メソッドを実行する ... emit属性
* cf emit = 放出する
イメージ
// 子側 (親を呼び出す際に、$emit()をコールするdx) this.$emit('【親側の属性】'); // 親 <子コンポーネント @【親側の属性】="【親側のメソッド】" > private 【親側のメソッド】() { // 何らかの処理 }
【3】サンプル
Dialog.vue (子コンポーネント)
<template> <v-dialog persistent width="600px" v-model="this.isVisible"> <v-card> <v-card-title class="headline grey lighten-2"> {{ this.title }} </v-card-title> <v-card-text> {{ this.message }} <div> {{ this.parentValue }} </div> </v-card-text> <v-card-actions> <v-btn color="primary" text @click="close()" > OK </v-btn> <v-btn color="secondary" text @click="showParentValue()" > Show Parent Value Demo </v-btn> <v-btn color="primary" text @click="callParent()" > Call Parent </v-btn> </v-card-actions> </v-card> </v-dialog> </template> <script lang="ts"> import { Component, Prop, Vue, } from 'vue-property-decorator'; @Component export default class Dialog extends Vue { @Prop() title!: string; @Prop() message!: string; private isVisible = false; private parentValue = ''; created() { this.isVisible = false; } public open(): void { this.isVisible = true; } public close(): void { this.isVisible = false; } private showParentValue() { this.parentValue = `parentValue = ${this.$parent.$data.helloValue}`; } private callParent() { this.$emit('callFromChild', 'Mike'); } } </script>
Demo.vue (親コンポーネント)
<template> <div class="home"> <div> Hello! <v-btn @click="openDialog()">Open</v-btn> <div> {{ this.childValue }} </div> <div> {{ this.value }} </div> </div> <Dialog ref="dialog" title="Title" message="HelloWorld" @callFromChild="showSomethingFromChild" > </Dialog> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import Dialog from '@/components/Dialog.vue'; @Component({ components: { Dialog, }, }) export default class Demo extends Vue { public helloValue = 'Hello'; isShownDialog = false; value = ''; get refs(): any { return this.$refs; } openDialog() { this.refs.dialog.open(); } private showSomethingFromChild(name: string) { this.value = `From Child : ${name}`; } } </script>
参考文献
https://tomcky.hatenadiary.jp/entry/2018/03/23/064243
https://qiita.com/ryo2132/items/4d43209ea89ad1297426
https://kagasu.hatenablog.com/entry/2017/07/29/114654
https://qiita.com/shosho/items/b9b24a52dc0cc0fc33f5
関連記事
Vue ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/04/30/000000