この記事では主に Vue2.0 の親コンポーネントと子コンポーネント間のイベント ディスパッチの仕組みを紹介しますので、参考にしてください。
vue1.x から来た人なら誰でも、vue2.0 では、親コンポーネントと子コンポーネント間のイベント通信のための $dispatch と $broadcase が削除されていることを知っています。公式の考慮事項は、コンポーネント ツリー構造に基づくイベント フロー手法は非常に理解しにくく、コンポーネント構造が拡大するにつれてますます脆弱になるということです。特にコンポーネントの階層が比較的深い場合はそうです。放送やイベント配信という仕組みを通して、さらにわかりにくくなっているように思えます。
廃止と同時に、公式は空の vue インスタンスのインスタンス化やサブコンポーネントの状態変更に反応するための $emit の使用などの代替ソリューションも提供しています
1. $emit を親として使用してイベントをトリガーします
。 vue のコンポーネントでは、dialogConfigVisible 変数はサブコンポーネントのポップアップ ボックスの表示または非表示を制御します。
configBox.vue は、カプセル化されたアナウンス ポップアップ ウィンドウであると仮定して、サブコンポーネントとして使用されます。
親コンポーネント helloWorld.vue 内で
<config-box :visible="dialogConfigVisible" @listenToConfig="changeConfigVisible" > </config-box>
script
data(){ return { dialogConfigVisible:true } } methods: { changeConfigVisible(flag) { this.dialogConfigVisible = flag; } }
次に、子コンポーネント configBox.vue で、主にイベント コールバック内で $emit を使用してカスタム listenToConfig イベントをトリガーします。後でパラメーターを追加して、親コンポーネントに渡すこともできます。たとえば、サブコンポーネントのポップアップ ウィンドウで [×] をクリックして閉じると、親コンポーネント helloWorld.vue にそれを閉じたいことが通知されます。これは主に、親コンポーネントが対応する状態変数を変更して渡すことを容易にするためです。カスタム イベントには false。
script
methods:{ dialogClose() { this.show = false; this.$emit("listenToConfig", false) } }
子コンポーネントで、listenToConfig イベントをアクティブにトリガーし、パラメータ false を渡して、helloWorld.vue ダイアログ ボックスが閉じようとしていることを親コンポーネントに伝えます。ここでは、親コンポーネントの状態が変更されていないことを回避でき、ページが再度更新されたときにダイアログ ボックスが自動的に表示されます。
2. 空の vue インスタンス バスをインスタンス化します
ここでは、主にサブコンポーネントと親コンポーネント間の通信を均一に管理するために、バスを媒体として使用して、バスの空の vue インスタンスをインスタンス化します。まず、新しいバスを作成します。 js ファイル内に新しいオブジェクトを作成します。親コンポーネントは table.vue、子コンポーネントは tableColumn.vue です
// bus.js import Vue from "vue"; export var bus = new Vue({ data:{ scrollY:false }, methods:{ updateScrollY(flag){ this.scrollY = flag; } } })
次に、それぞれを導入します:
// table.vue <script> import {bus} from "./bus" export default { created(){ bus.$on('getData',(argsData)=>{ // 这里获取子组件传来的参数 console.log(argsData); }) } } </script>
// tableColumn.vue <script> import {bus} from "./bus" export default{ methods(){ handleClick(){ bus.$emit('getData',{data:"from tableColumn!"}) } } } </script>
上記の親コンポーネントと子コンポーネントでは、親コンポーネントはバスを使用して登録しますリスニング イベント getData が存在すると、ステータスが変化すると、バス上の対応するイベントがトリガーされます。
この空のインスタンスの使用方法は、イベント センターの作成と同等であるため、この種の通信は、親コンポーネントと子コンポーネント以外のコンポーネント間の通信にも適しています
3.通信を実装する 2 つのコンポーネントは、直接の親子コンポーネントではなく、祖父と孫、またはより多くのレベルにまたがる親子コンポーネントです。子コンポーネントがレベルごとにパラメータを渡すことは不可能です。コミュニケーションの目的ですが、私たちが現在理解しているコミュニケーションはすべてこの方法で中継されます。ターゲットの親コンポーネントが見つかるまで while ループを上方向にトラバースし続け、対応するコンポーネントでイベントをトリガーできます。
以下は、element-ui によって実装された親子コンポーネント通信ミックスインで、コンポーネントの同期に大きな役割を果たします。このコンポーネントの通信は、element-ui の利点の概要でも特に説明されていますfunction broadcast(componentName, eventName, params) { // 向下遍历每个子节点,触发相应的向下广播的 事件 this.$children.forEach(child => { var name = child.$options.componentName; if (name === componentName) { child.$emit.apply(child, [eventName].concat(params)); } else { broadcast.apply(child, [componentName, eventName].concat([params])); } }); } export default { methods: { // 向上遍历父节点,来获取指定父节点,通过$emit 在相应的 组件中触发 eventName 事件 dispatch(componentName, eventName, params) { var parent = this.$parent || this.$root; var name = parent.$options.componentName; // 上面的componentName 需要在每个vue 实例中额外配置自定义属性 componentName, //可以简单替换成var name = parent.$options._componentTag; while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.componentName; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, broadcast(componentName, eventName, params) { broadcast.call(this, componentName, eventName, params); } } };
<f1> <c1></c1> </f1>
c2.vue
<template> <section> <button type="button" name="button" @click="dispatchTest">点击一下,就可以</button> </section> </template> <script type="text/javascript"> import Emitter from "../mixins/emitter"; export default { name: "c2", mixins: [Emitter], componentName:'c2', methods: { dispatchTest() { this.dispatch('f1', 'listenerToC1', false); } } } </script>
<template type="html"> <p class="outBox-class"> <slot> </slot> </p> </template> <script type="text/javascript"> import Emitter from "../mixins/emitter"; export default { name: "f1", mixins: [Emitter], componentName: 'f1', mounted() { this.$on("listenerToC1", (value) => { alert(value); }) } } </script>
js で現在時刻をフォーマットするには?
vue を使用して CSS を導入する、関連する質問は少ない
以上がVue2.0の親コンポーネントと子コンポーネント間のディスパッチ機構の実装について(詳細チュートリアル)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。