子コンポーネントから別の子にデータをリレーする方法
by bc_rikko
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.0/css/bulma.min.css">
<h1 class="title">子から別の子にデータを渡す方法</h1>
<h2 class="subtitle">子→親→子でデータをリレーする</h2>
<!--============================================
親コンポーネントが橋渡しする方法
============================================-->
<div id="parent-a" class="container">
<h3 class="title is-4">方法1)親コンポーネントが橋渡しする方法</h3>
<!-- Parent -->
<div class="field">
<label class="label">parent</label>
<p class="subtitle" v-text="parentText"></p>
</div>
<!-- Child1 -->
<child-a-1 v-model="parentText"></child-a-1>
<!-- Child2 -->
<child-a-2 :text="parentText"></child-a-2>
</div>
<script type="text/x-template" id="child-a-1">
<div class="field">
<label class="label">child-a-1</label>
<input class="input" type="text" @input="changeInput">
</div>
</script>
<script type="text/x-template" id="child-a-2">
<div class="field">
<label class="label">child-a-2</label>
<p class="subtitle" v-text="text"></p>
</div>
</script>
<!--============================================
子1からEventEmitで子2に渡す方法
============================================-->
<div id="parent-b" class="container">
<h3 class="title is-4">方法2)子1からEventEmitで子2に渡す方法</h3>
<!-- Child1 -->
<child-b-1></child-b-1>
<!-- Child2 -->
<child-b-2></child-b-2>
</div>
<script type="text/x-template" id="child-b-1">
<div class="field">
<label class="label">child-b-1</label>
<input class="input" type="text" v-model="text">
<button class="button is-light" @click="submit">Sent Text to Child-B-2</button>
</div>
</script>
<script type="text/x-template" id="child-b-2">
<div class="field">
<label class="label">child-b-2</label>
<p class="subtitle" v-text="text"></p>
</div>
</script>
CSS
body {
margin: 10px;
}
.container {
margin: 20px;
padding: 10px;
border: 4px dashed rgba(0,0,0,.5)
}
JavaScript
// import [email protected] [email protected]
// x-templateはデモや極小アプリ以外は非推奨
/******************************************
* 1.親コンポーネントが橋渡しする
* ※ this.$emitやthis.$parent.$emitの部分をグローバルVM経由で実行することも可能
* 参考: https://jp.vuejs.org/v2/guide/components.html#親子間以外の通信
*******************************************/
const ChildA1 = Vue.component('child-a-1', {
template: '#child-a-1',
methods: {
changeInput (e) {
// v-modelで指定したparentTextを変更するイベント
this.$emit('input', e.target.value);
}
}
});
const ChildA2 = Vue.component('child-a-2', {
template: '#child-a-2',
props: {
// 親からtextをもらう
text: String
}
});
const vm1 = new Vue({
el: "#parent-a",
components: {
ChildA1,
ChildA2
},
data () {
return {
parentText: ''
}
}
});
/******************************************
* 2.子1からEventEmitで子2に渡す方法
*******************************************/
const vm = new Vue();
const ChildB1 = Vue.component('child-b-1', {
template: '#child-b-1',
data () {
return {
text: ''
}
},
methods: {
submit () {
// send-textイベントを発火させる
vm.$emit('send-text', this.text)
}
}
});
const ChildB2 = Vue.component('child-b-2', {
template: '#child-b-2',
data () {
return {
text: ''
}
},
created () {
// どこから来るかわからないけど`send-text`イベントを待ち受ける
vm.$on('send-text', this.changeText)
},
methods: {
changeText (text) {
this.text = text;
}
}
});
const vmB = new Vue({
el: "#parent-b",
components: {
ChildB1,
ChildB2
}
});