您的位置:首页 > 产品设计 > UI/UE

Vuejs——(10)组件——父子组件通信

2016-09-05 21:20 507 查看
版权声明:我萌么~萌!么么哒~

目录(?)[+]

 

本篇资料来于官方文档:

http://cn.vuejs.org/guide/components.html#u7236_u5B50_u7EC4_u4EF6_u901A_u4FE1


本文是在官方文档的基础上,更加细致的说明,代码更多更全。

简单来说,更适合新手阅读

 

(二十七)父子组件通信

①访问子组件、父组件、根组件;

this.$parent    访问父组件

this.$children   访问子组件(是一个数组)

this.$root            根实例的后代访问根实例

示例代码:

[html] view
plain copy

 





<div id="app">  

    父组件:  

    <input v-model="val"><br/>  

    子组件:  

    <test :test="val"></test>  

</div>  

<script>  

    var vm = new Vue({  

        el: '#app',  

        data: {  

            val: 1  

        },  

        components: {  

            test: {  

                props: ['test'],  

                template: "<input @keyup='findParent' v-model='test'/>",  

                methods: {  

                    findParent: function () {  

                        console.log(this.$parent);  //访问根组件  

                        console.log(this.$parent.val);  //访问根组件的val属性  

                        console.log(this.$parent.$children.indexOf(this));  //查看当前能否在其父组件的子组件中找到索引  

                        console.log(this.$parent === this.$root);   //查看父组件和根组件是不是全等的(因为他的父组件就是根组件)  

                    }  

                }  

            }  

        }  

    });  

</script>  

当在子组件的输入框按键弹起时,显示内容依次为:

父组件、父组件的输入框的值(默认情况是1)、0(表示是父组件的children属性中的第一个元素)、true(由于父组件就是根组件,所以是全等的);

 

通过这样的方法,可以在组件树中进行互动。

 

②自定义事件:

首先,事件需要放置在events属性之中,而不是放置在methods属性中(新手很容易犯的错误),只能触发events属性中的事件,而methods属性中的事件是无法触发的。
事件
说明
$on(事件名)
事件名的类型是字符串(下同),调用它可以通过this.$on()来调用;
$emit(事件名, 参数)
用于触发事件,参数是用于传递给事件的参数。这个用于触发同级事件(当前组件的)
$dispatch(事件名, 参数)
①向上派发事件,用于向父组件传播。

②会首先触发当前组件的同名事件(如果有);

③然后会向上冒泡,当遇到第一个符合的父组件的事件后触发并停止;

④当父组件的事件的返回值设为true会继续冒泡去找下一个。
$broadcast(事件名, 参数)
①向下广播事件,用于向所有子组件传播。

②默认情况是仅限子组件;

③子组件事件的返回值是true,才会继续向该子组件的孙组件派发;

④不会触发自身同名事件;
 

其次,向上派发和向下广播有所区别:向上派发会触发自身同名事件,而向下广播不会;

 

第三,向上派发和向下广播默认只会触发直系(子或者父,不包括祖先和孙)的事件,除非事件返回值为true,才会继续在这一条线上继续。

 

第四,事件不能显式的通过 this.事件名 来调用它。

 

示例代码:

[html] view
plain copy

 





<div id="app">  

    父组件:  

    <button @click="parentClick">点击向下传播broadcast</button>  

    <br/>  

    子组件1:  

    <children1></children1>  

    <br/>  

    另一个子组件1:  

    <another-children1></another-children1>  

</div>  

<script>  

    var vm = new Vue({  

        el: '#app',  

        data: {  

            val: 1  

        },  

        methods: {  

            parentClick: function () {  

                this.$broadcast("parentClick", "abc");  

            }  

        },  

        events: {  

            childrenClick: function () {  

                console.log("childrenClick-Parent");  

            },  

            parentClick: function () {  

                console.log("parentClick-Parent");  

                return true;  

            }  

        },  

        components: {  

            children1: {    //这个无返回值,不会继续派发  

                props: ['test'],  

                template: "<button>children1</button></br>子组件2:<children2></children2>",  

                events: {  

                    childrenClick: function () {  

                        console.log("childrenClick-children1");  

                    },  

                    parentClick: function (msg) {  

                        console.log("parentClick-Children1");  

                        console.log("message:" + msg);  

                    }  

                },  

                components: {  

                    children2: {  

                        props: ['test'],  

                        template: "<button @click='findParent'>children-Click</button>",  

                        methods: {  

                            findParent: function () {  

                                this.$dispatch('childrenClick');  

                            }  

                        },  

                        events: {  

                            childrenClick: function () {  

                                console.log("childrenClick-children2");  

                            },  

                            parentClick: function (msg) {  

                                console.log("parentClick-Children2");  

                                console.log("message:" + msg);  

                            }  

                        }  

                    }  

                }  

            },  

            anotherChildren1: { //这个是返回值为true,会继续向子组件的子组件派发  

                props: ['test'],  

                template: "<button>anotherChildren1</button></br>另一个子组件2:<another-children2></another-children2>",  

                events: {  

                    childrenClick: function () {  

                        console.log("childrenClick-anotherChildren1");  

                        return true;  

                    },  

                    parentClick: function (msg) {  

                        console.log("parentClick-anotherChildren1");  

                        console.log("message:" + msg);  

                        return true;  

                    }  

                },  

                components: {  

                    anotherChildren2: {  

                        props: ['test'],  

                        template: "<button @click='findParent'>anotherChildren2-Click</button>",  

                        methods: {  

                            findParent: function () {  

                                this.$dispatch('childrenClick');  

                            }  

                        },  

                        events: {  

                            childrenClick: function () {  

                                console.log("childrenClick-anotherChildren2");  

                            },  

                            parentClick: function (msg) {  

                                console.log("parentClick-anotherChildren2");  

                                console.log("message:" + msg);  

                            }  

                        }  

                    }  

                }  

            }  

  

        }  

    });  

</script>  

               },  

                            parentClick: function () {  

                                console.log("parentClick-anotherChildren2");  

                            }  

                        }  

                    }  

                }  

            }  

  

        }  

    });  

</script>  

 

说明:

【1】点击父组件的按钮,会向下广播,然后触发子组件1本身,另外一个子组件1,以及另一个子组件2;

【2】点击子组件2的按钮,会触发子组件2的事件和子组件1的事件,但不会触发父组件的按钮;

【3】点击另一个子组件2的按钮,会触发另一个子组件2的事件,另一个子组件1的事件和父组件的事件(因为另一个子组件1的事件的返回值为true);

 

 

 

③使用v-on绑定自定义事件:

【1】简单来说,子组件触发某个事件(events里的方法)时,父组件也会执行某个方法(父组件methods里的方法)。

 

【2】触发的绑定写在模板之中(即被替换的那个template模板中),可以多个子组件的事件绑定一个父组件的方法,或者不同子组件的事情绑定不同父组件的方法,但是不能同一个子组件事件绑定多个父组件的方法。

 

【3】子组件派发消息传递的参数,即使子组件的事件没有参数,也不影响将参数传递给父组件的方法(即父组件的方法可以接受到子组件方法获取的参数)

 

如示例:

[html] view
plain copy

 





<div id="app">  

    父组件:  

    <button>点击向下传播broadcast</button>  

    <br/>  

    子组件1:  

    <!--绑定写在这里,可以多个绑定同一个,或者不同绑定不同的,但不能一个绑定多个-->  

    <children v-on:test="parent" @test2="another"></children>  

</div>  

<script>  

    var vm = new Vue({  

        el: '#app',  

        data: {  

            val: 1  

        },  

        methods: {  

            parent: function (arg) {  

                console.log(arg);  

                console.log("the first method with test event");  

            },  

            another: function () {  

                console.log("another method");  

            }  

        },  

        components: {  

            children: {    //这个无返回值,不会继续派发  

                props: ['test'],  

                template: "<button @click='childClick'>children1</button></br><button @click='childClick2'>children1</button>",  

                methods: {  

                    childClick: function () {  

                        this.$emit("test", 'the argument for dispatch');  

                    },  

                    childClick2: function () {  

                        this.$emit("test2");  

                    }  

                },  

                events: {  

                    test: function () {  

                        console.log("test");  

                    },  

                    test2: function () {  

                        console.log("test2");  

                    }  

                }  

            }  

        }  

    });  

</script>  

 

④子组件索引

简单来说:就是可以直接从索引获取到子组件,然后就可以调用各个子组件的方法了。

 

添加索引方法是:在标签里添加v-ref:索引名

调用组件方法是:vm.$ref.索引名

也可以直接在父组件中使用this.$ref.索引名

这个时候,就可以获得组件了,然后通过组件可以调用他的方法,或者是使用其数据。

 

示例代码:

[html] view
plain copy

 





<div id="app">  

    父组件:  

    <button @click="todo">触发子组件的事件</button>  

    <br/>  

    子组件1:  

    <!--绑定写在这里,可以多个绑定同一个,或者不同绑定不同的,但不能一个绑定多个-->  

    <children v-ref:child></children>  

</div>  

<script>  

    var vm = new Vue({  

        el: '#app',  

        methods: {  

            todo: function () {  

                this.$refs.child.fromParent();  //通过索引调用子组件的fromParent方法  

            }  

        },  

        components: {  

            children: {    //这个无返回值,不会继续派发  

                props: ['test'],  

                template: "<button>children1</button>",  

                methods: {  

                    fromParent: function () {  

                        console.log("happened fromParent by ref");  

                    }  

                }  

            }  

        }  

    });  

</script>  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: