Vue.js インスタンスを生成し再描画する時に`v-on`ディレクティブがある場合
motivation
Vueのインスタンスを生成して子コンポーネントを再描画するときに、v-on
ディレクティブを設定する方法にたどり着くのが大変だったのでメモ。
前回の記事: Vue.js 子コンポーネントを強制的に再描画するいくつかの方法
outline
prerequisites
versions
- vue: 2.6.10
- core-js: 2.6.5
components
子コンポーネントに$emit
を配置。イベント名はecho
。
▼ EmitChild.vue
<template> <div> <p>{{ count }}</p> <button @click="increment">+ 1</button> <button @click="emit">emit</button> </div> </template> <script> export default { name: "EmitChild", data() { return { count: 0 }; }, methods: { increment() { this.count++; }, emit() { this.$emit("echo", this.count); } } }; </script>
solutions
Vueのインスタンスメソッドのvm.$on(event, callback)
を追加することで解決できた。
emit-instance
<template> <div> <button @click="toggle">rerender by emit instance</button> <div ref="parent"> <emit-child @echo="echo"></emit-child> </div> <p v-if="echo">echo: {{ text }}</p> </div> </template> <script> import Vue from "vue"; import EmitChild from "./EmitChild.vue"; export default { name: "Key", components: { EmitChild }, data() { return { text: "" }; }, methods: { toggle() { this.$refs["parent"].textContent = null; const ComponentClass = Vue.extend(EmitChild); const instance = new ComponentClass(); instance.$mount(); instance.$on("echo", e => this.echo(e)); this.$refs["parent"].appendChild(instance.$el); }, echo(e) { this.text = e; } } }; </script>
failure
解決策にたどり着くまでの失敗。
propsData
propsにいれてみる。この方法だと親から渡したい値はpropsとして渡るが、イベントの購読はできない。
toggle() { this.$refs["parent"].textContent = null; const ComponentClass = Vue.extend(EmitChild); const instance = new ComponentClass({ propsData: this.echo }); instance.$mount(); this.$refs["parent"].appendChild(instance.$el); },
references
- API — Vue.js, 入手先 https://jp.vuejs.org/v2/api/#vm-on
- 作者:MIO
- 発売日: 2018/05/29
- メディア: Kindle版