vueスロットslotピット--親コンポーネント通信
vueコンポーネントをカプセル化する場合、サブコンポーネントのネストにスロットslotが使用されるのは避けられません.では、slotスロットのコンテンツコンポーネントが親コンポーネントと通信する必要がある場合、どうすればいいのでしょうか.シーンコードは次のとおりです.
使用する場合、以下のようになります.
まず、vueでは、サブコンポーネントが親コンポーネントに通信するときに、サブコンポーネントにカスタムイベントを配布し、親コンポーネントのサブコンポーネント参照先でカスタムイベントをリスニングすることを知っています(@test=「demo」):
ただし、スロットslotではカスタムイベントの傍受はできません.言い換えれば、この書き方は間違っています.
では、どうやってこの問題を解決しますか?実は方法はたくさんありますが、筆者はここで自分の解決策を話します.
サブコンポーネントで親コンポーネントを呼び出してカスタムイベントをトリガーし、親コンポーネント独自のライフサイクル関数でカスタムイベントをリスニングできます.codeは次のとおりです.
ここでは、slotを含むコンポーネントのVueインスタンスの参照を見つけ、そのコンポーネントのインスタンスに約束されたカスタムイベントを自分でトリガーさせ、自分のVueインスタンスが初期化されたときにこのカスタムイベントをリスニング$onしたため、自分のインスタンスが$emitの形でカスタムイベントをトリガーすると、リスニングされたイベントは対応するコールバックをトリガーします.通信の目的を達成する.
この例を見つけるのも簡単ですが、上記のように$parent($children)を利用する形式はそのうちの1つにすぎません.別の形式($refs)を見てみましょう.
もう1つの方法は、VueのプロトタイプにVueインスタンス、すなわちeventBusをマウントし、VueインスタンスのeventBusを用いてコンポーネント間の通信を行うことである.さらにvuexも利用できますが、個人的には必要ないと思います.
これにより、slotスロットと親コンポーネントの通信の問題を解決できます.
カスタムイベントのリスニングの説明:vueの$onの説明
// parent.vue
export default {
methods: {
},
}
// child.vue
export default {
methods: {
onInput(){}
},
}
使用する場合、以下のようになります.
まず、vueでは、サブコンポーネントが親コンポーネントに通信するときに、サブコンポーネントにカスタムイベントを配布し、親コンポーネントのサブコンポーネント参照先でカスタムイベントをリスニングすることを知っています(@test=「demo」):
// parent.vue
import child from 'child.vue'
export default {
components:{child},
methods: {
demo(val) {
console.log(val)
}
},
}
// child.vue
export default {
methods: {
onInput(e) {
this.$emit('test', e.target.value)
}
},
}
ただし、スロットslotではカスタムイベントの傍受はできません.言い換えれば、この書き方は間違っています.
では、どうやってこの問題を解決しますか?実は方法はたくさんありますが、筆者はここで自分の解決策を話します.
サブコンポーネントで親コンポーネントを呼び出してカスタムイベントをトリガーし、親コンポーネント独自のライフサイクル関数でカスタムイベントをリスニングできます.codeは次のとおりです.
// parent.vue
export default {
mounted(){
this.$on('test', this.fn)
},
methods: {
fn(val){
console.log(val)
}
},
}
// child.vue
export default {
methods: {
onInput(e){
this.$parent.$emit("test", e.target.value)
}
},
}
ここでは、slotを含むコンポーネントのVueインスタンスの参照を見つけ、そのコンポーネントのインスタンスに約束されたカスタムイベントを自分でトリガーさせ、自分のVueインスタンスが初期化されたときにこのカスタムイベントをリスニング$onしたため、自分のインスタンスが$emitの形でカスタムイベントをトリガーすると、リスニングされたイベントは対応するコールバックをトリガーします.通信の目的を達成する.
この例を見つけるのも簡単ですが、上記のように$parent($children)を利用する形式はそのうちの1つにすぎません.別の形式($refs)を見てみましょう.
// parent.vue ( slot )
export default {
mounted(){
this.$on('test', this.fn)
},
methods: {
fn(val){
console.log(val)
}
},
}
// parent
// Test.vue
import Parent from './parent.vue'
export default {
components: {parent},
methods: {
clickFn() {
this.$refs.parent.$emit('test', 666)
}
},
}
もう1つの方法は、VueのプロトタイプにVueインスタンス、すなわちeventBusをマウントし、VueインスタンスのeventBusを用いてコンポーネント間の通信を行うことである.さらにvuexも利用できますが、個人的には必要ないと思います.
これにより、slotスロットと親コンポーネントの通信の問題を解決できます.
カスタムイベントのリスニングの説明:vueの$onの説明