Vue コンポーネント間で通信するにはどうすればよいですか?手法の紹介

青灯夜游
リリース: 2020-10-26 17:54:45
転載
2207 人が閲覧しました

Vue コンポーネント間で通信するにはどうすればよいですか?手法の紹介

コンポーネント通信

子コンポーネントは this.$parent を使用して親コンポーネントとその親チェーン上の任意のインスタンスにアクセスできますが、子コンポーネントは親コンポーネントのデータに直接依存することを避け、明示的に props を使用してデータを渡すようにする必要があります。

さらに、子コンポーネント内で親コンポーネントの状態を変更することは非常に悪い習慣です。

  • これにより、親コンポーネントと子コンポーネントが作成されてしまいます。密結合;

  • 親コンポーネントを見ただけでは状態を理解するのは困難です。サブコンポーネントによって変更される可能性があるためです。理想的には、コンポーネント自体のみがその状態を変更できます。

各 Vue インスタンスはイベント トリガーです:

  • $on() - イベントをリッスンします。

  • $emit() - イベントをスコープ チェーンの上にディスパッチします。 (トリガーイベント)

  • $dispatch() - 親チェーンに沿ってバブルアップするイベントをディスパッチします。

  • $broadcast()—イベントをブロードキャストし、そのイベントをすべての子孫に下方に伝播します。

監視とトリガー

v-on はカスタム イベントをリッスンします:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <!--子组件模板-->
        <template id="child-template">
            <input v-model="msg" />
            <button v-on:click="notify">Dispatch Event</button>
        </template>
        <!--父组件模板-->
        <div id="events-example">
            <p>Messages: {{ messages | json }}</p>
            <child v-on:child-msg="handleIt"></child>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
//        注册子组件
//        将当前消息派发出去
        Vue.component(&#39;child&#39;, {
            template: &#39;#child-template&#39;,
            data: function (){
                return { msg: &#39;hello&#39; }
            },
            methods: {
                notify: function() {
                    if(this.msg.trim()){
                        this.$dispatch(&#39;child-msg&#39;,this.msg);
                        this.msg = &#39;&#39;;
                    }
                }
            }
        })
//        初始化父组件
//        在收到消息时将事件推入一个数组中
        var parent = new Vue({
            el: &#39;#events-example&#39;,
            data: {
                messages: []
            },
            methods:{
                &#39;handleIt&#39;: function(){
                    alert("a");
                }
            }
        })
    </script>
</html>
ログイン後にコピー

Vue コンポーネント間で通信するにはどうすればよいですか?手法の紹介

#親コンポーネントは、子コンポーネントによってトリガーされたイベントをリッスンするために子コンポーネントが使用される v-on を直接使用できます。コンポーネントイベントのルート要素。 .native を使用して v-on を変更できます。例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="counter-event-example">
          <p>{{ total }}</p>
          <button-counter v-on:increment="incrementTotal"></button-counter>
          <button-counter v-on:increment="incrementTotal"></button-counter>
        </div>
    </body>
    <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        Vue.component(&#39;button-counter&#39;, {
          template: &#39;<button v-on:click="increment">{{ counter }}</button>&#39;,
          data: function () {
            return {
              counter: 0
            }
          },
          methods: {
            increment: function () {
              this.counter += 1
              this.$emit(&#39;increment&#39;)
            }
          },
        })
        new Vue({
          el: &#39;#counter-event-example&#39;,
          data: {
            total: 0
          },
          methods: {
            incrementTotal: function () {
              this.total += 1
            }
          }
        })
    </script>
</html>
ログイン後にコピー

ディスパッチ イベント - $dispatch()Vue コンポーネント間で通信するにはどうすればよいですか?手法の紹介

<my-component v-on:click.native="doTheThing"></my-component>
ログイン後にコピー

サブコンポーネントのボタン要素は、次のようにバインドされます。このイベントは、通知メソッドを指しますVue コンポーネント間で通信するにはどうすればよいですか?手法の紹介

  1. 子コンポーネントの通知メソッドが処理されると、$dispatch が呼び出され、イベントは子コンポーネントの子メッセージ イベントにディスパッチされます。親コンポーネント、およびイベントが提供される msg パラメータ

  2. 子メッセージ イベントは、親コンポーネントの events オプションで定義されます。親コンポーネントが子のディスパッチを受信した後、コンポーネントでは、child-msg イベントを呼び出します。

  3. イベントのブロードキャスト - $broadcast()

  4. <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="app">
                <p>Messages: {{ messages | json }}</p>
                <child-component></child-component>
            </div>
            <template id="child-component">
                <input v-model="msg" />
                <button v-on:click="notify">Dispatch Event</button>
            </template>
    
        <script src="js/vue.js"></script>
        <script>
            // 注册子组件
            Vue.component(&#39;child-component&#39;, {
                template: &#39;#child-component&#39;,
                data: function() {
                    return {
                        msg: &#39;&#39;
                    }
                },
                methods: {
                    notify: function() {
                        if (this.msg.trim()) {
                            this.$dispatch(&#39;child-msg&#39;, this.msg)
                            this.msg = &#39;&#39;
                        }
                    }
                }
            })
        
            // 初始化父组件
            new Vue({
                el: &#39;#app&#39;,
                data: {
                    messages: []
                },
                events: {
                    &#39;child-msg&#39;: function(msg) {
                        this.messages.push(msg)
                    }
                }
            })
        </script>
        </body>
    </html>
    ログイン後にコピー
イベントのディスパッチの逆。前者は子コンポーネントにバインドされ、$dispatch を呼び出して親コンポーネントにディスパッチします。後者は親コンポーネントにバインドされ、$broadcast を呼び出して子コンポーネントにブロードキャストします。

#親コンポーネントと子コンポーネント間のアクセス

親コンポーネントが子コンポーネントにアクセスする: $children または $refs を使用します

    子コンポーネントは親コンポーネントにアクセスします: $parent を使用します
  • 子コンポーネントがルート コンポーネントにアクセスします: $root
  • $children を使用します:
  • <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="app">
                <input v-model="msg" />
                <button v-on:click="notify">Broadcast Event</button>
                <child-component></child-component>
            </div>
            
            <template id="child-component">
                <ul>
                    <li v-for="item in messages">
                        父组件录入了信息:{{ item }}
                    </li>
                </ul>
            </template>
    
        <script src="js/vue.js"></script>
        <script>
            // 注册子组件
            Vue.component(&#39;child-component&#39;, {
                template: &#39;#child-component&#39;,
                data: function() {
                    return {
                        messages: []
                    }
                },
                events: {
                    &#39;parent-msg&#39;: function(msg) {
                        this.messages.push(msg)
                    }
                }
            })
            // 初始化父组件
            new Vue({
                el: &#39;#app&#39;,
                data: {
                    msg: &#39;&#39;
                },
                methods: {
                    notify: function() {
                        if (this.msg.trim()) {
                            this.$broadcast(&#39;parent-msg&#39;, this.msg)
                        }
                    }
                }
            })
        </script>
        </body>
    </html>
    ログイン後にコピー

$ref は子コンポーネントのインデックス ID を指定できます:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <parent-component></parent-component>
        </div>
        
        <template id="parent-component">
            <child-component1></child-component1>
            <child-component2></child-component2>
            <button v-on:click="showChildComponentData">显示子组件的数据</button>
        </template>
        
        <template id="child-component1">
            <h2>This is child component 1</h2>
        </template>
        
        <template id="child-component2">
            <h2>This is child component 2</h2>
        </template>
        <script src="js/vue.js"></script>
        <script>
            Vue.component(&#39;parent-component&#39;, {
                template: &#39;#parent-component&#39;,
                components: {
                    &#39;child-component1&#39;: {
                        template: &#39;#child-component1&#39;,
                        data: function() {
                            return {
                                msg: &#39;child component 111111&#39;
                            }
                        }
                    },
                    &#39;child-component2&#39;: {
                        template: &#39;#child-component2&#39;,
                        data: function() {
                            return {
                                msg: &#39;child component 222222&#39;
                            }
                        }
                    }
                },
                methods: {
                    showChildComponentData: function() {
                        for (var i = 0; i < this.$children.length; i++) {
                            alert(this.$children[i].msg)
                        }
                    }
                }
            })
        
            new Vue({
                el: &#39;#app&#39;
            })
        </script>
    </body>
</html>
ログイン後にコピー

効果は $children と同じです。

Vue コンポーネント間で通信するにはどうすればよいですか?手法の紹介$parent:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <parent-component></parent-component>
        </div>
        
        <template id="parent-component">
            <!--<child-component1></child-component1>
            <child-component2></child-component2>-->
            <child-component1 v-ref:cc1></child-component1>
            <child-component2 v-ref:cc2></child-component2>
            <button v-on:click="showChildComponentData">显示子组件的数据</button>
        </template>
        
        <template id="child-component1">
            <h2>This is child component 1</h2>
        </template>
        
        <template id="child-component2">
            <h2>This is child component 2</h2>
        </template>
        <script src="js/vue.js"></script>
        <script>
            Vue.component(&#39;parent-component&#39;, {
                template: &#39;#parent-component&#39;,
                components: {
                    &#39;child-component1&#39;: {
                        template: &#39;#child-component1&#39;,
                        data: function() {
                            return {
                                msg: &#39;child component 111111&#39;
                            }
                        }
                    },
                    &#39;child-component2&#39;: {
                        template: &#39;#child-component2&#39;,
                        data: function() {
                            return {
                                msg: &#39;child component 222222&#39;
                            }
                        }
                    }
                },
                methods: {
                    showChildComponentData: function() {
//                        for (var i = 0; i < this.$children.length; i++) {
//                            alert(this.$children[i].msg)
//                        }
                        alert(this.$refs.cc1.msg);
                        alert(this.$refs.cc2.msg);
                    }
                }
            })
            new Vue({
                el: &#39;#app&#39;
            })
        </script>
    </body>
</html>
ログイン後にコピー

冒頭で述べたように、子コンポーネントで親コンポーネントの状態を変更することはお勧めできません。

非親子コンポーネント通信Vue コンポーネント間で通信するにはどうすればよいですか?手法の紹介

非親子関係を持つコンポーネントも通信する必要がある場合があります。単純なシナリオでは、空の Vue インスタンスを中央イベント バスとして使用します:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <parent-component></parent-component>
        </div>
        
        <template id="parent-component">
            <child-component></child-component>
        </template>
        
        <template id="child-component">
            <h2>This is a child component</h2>
            <button v-on:click="showParentComponentData">显示父组件的数据</button>
        </template>
        
        <script src="js/vue.js"></script>
        <script>
            Vue.component(&#39;parent-component&#39;, {
                template: &#39;#parent-component&#39;,
                components: {
                    &#39;child-component&#39;: {
                        template: &#39;#child-component&#39;,
                        methods: {
                            showParentComponentData: function() {
                                alert(this.$parent.msg)
                            }
                        }
                    }
                },
                data: function() {
                    return {
                        msg: &#39;parent component message&#39;
                    }
                }
            })
            new Vue({
                el: &#39;#app&#39;
            })
        </script>
    </body>
</html>
ログイン後にコピー

関連する推奨事項:

2020 フロントエンド Vue インタビューの質問の概要(回答付き)


vue チュートリアルの推奨事項: 2020 年の最新の vue.js ビデオ チュートリアル 5 選

プログラミング関連の知識をさらに深めてください。訪問:

プログラミング入門! !

以上がVue コンポーネント間で通信するにはどうすればよいですか?手法の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート