//这是我的一个组件<msg v-ref:msgs></msg> //这时候,我们就为这个msg组件建立了一个msgs的索引//我们可以这样访问组件var vm = new Vue({}); var children = vm.$refs.msgs //通过这种方式访问我们的子组件//v-ref是一个数组或对象,是我们建立所有ref钩子的组件的集合这里,给大家看一张图,看一下parent,children, $refs相关的内容(好像图片有点模糊,不会整动态图,尴尬了,看得不清楚,大家可以自己建立一个demo打印出来好好!)
尽管我们可以这样直接访问整个实例里面的组件,但是不建议如此,因为子组件直接修改父组件的状态,是非常糟糕的,这会让父子组件紧密地耦合,理想的情况下,每个组件只能修改自己本身的状态,因为每个组件的作用域都是独立的;
这种情况下,vue也为我们带来了它们的自定义事件
使用 $dispatch() 派发事件,事件沿着父链冒泡;
使用 $broadcast() 广播事件,事件向下传导给所有的后代。
看起来,有点抽象,来个例子,就好理解很多了
//$dispatch()冒泡案例<!-- 实例 --><div id="app"><!-- 组件通讯一 --><section> <div class="mas-arry"><label for="">msg的数据:</label>{{ msg }} </div><!--子组件 --><msg></msg></section></div><template id="msg"><div class="inp"><input type="text" v-model="msg"><a href="javascript:;" @click="add_data">添加</a></div></template><script>Vue.component("msg",{ //这里直接使用了注册组件的语法糖的方式注册,简单快捷template: "#msg",data: function() {return {msg : "abc" }},methods: {add_data: function(){ //当点击这个事件的时候,就会触发$dispatch()方法;add_msg是父组件创建的监听子组件的方法,意思就是,告诉父组件的这个方法,老爸,我更新数据了,par_msg就是我更新的数据,你也快更新吧!把par_msg 的数据传给父组件更新!var par_msg = this.msg.trim();// this.$parent.add(par_msg); //此方式是直接操作父组件的方法this.$dispatch("add_msg", par_msg); //此方法是利用事件传播的方式this.msg = "";}}});var mvvm = new Vue({el: "#app",data: {msg : ["sgsg"]},events: { // 创建监听相应响应子组件的事件"add_msg": function(msg){ // add_msg 是用来监听子组件的方法,当接受到子组件的通知的时候,就把子组件更新的数据更新,这里的msg就是子组件的par_msgthis.msg.push(msg);}},methods: {add: function(msg){this.msg.push(msg);}}});</script>看完这段代码,相信大家都知道$dispatch()的冒泡的用法了,其实,就是这么点东西,里面有两个参数,第一个参数,就是父组件监听子组件events对象里面的一个方法名,两者要一致;第二个参数,就是子组件更新的数据,同时也是传递给给父组件要同步更新的数据,然后父组件就用这个参数来进行相应的操作
<!-- 组件通讯二 $broadcast()方法 --><section class="sec"><h3>父组件添加的数据源:</h3><div class="box clearfix"><label for="" class="box-left">id:</label><div class="bor-right"><input type="text" v-model="id"></div></div><div class="box clearfix"><label for="" class="box-left">姓名:</label><div class="bor-right"><input type="text" v-model="name"></div></div><div class="box clearfix"><label for="" class="box-left">爱好:</label><div class="bor-right"><input type="text" v-model="inst"></div></div><div class="box clearfix"><label for="" class="box-left"> </label><div class="bor-right"><a href="javascrip:;" @click="add_table">添加</a></div></div><h3>下面的表格是子组件信息:</h3><!-- 把父组件的table_data数据绑定到子组件上 --><broadcase :data="table_data"></broadcase></section><template id="broadcase"><div class="table"><table><thead><tr><th>id</th><th>姓名</th><th>爱好</th></tr></thead><tbody><tr v-for="list in data"><td>{{ list.id }}</td><td>{{ list.name }}</td><td>{{ list.inst }}</td></tr></tbody></table></div></template><script>Vue.component("broadcase",{ //这里直接使用了注册组件的语法糖的方式注册,简单快捷template: "#broadcase",props: ["data"], // props是用来接受父组件的传递参数,也可在里面自定义数据,如果数据需要有默认值的话,需在data里面定义data: function() {return {msg : "abc" }},events : { //这里只是个例子,子组件监听父组件的数据变化test : function(msg){console.log(msg);}},methods: {}});var mvvm = new Vue({el: "#app",data: {table_data: [{id: 1,name: "gjei",inst: "gjweir"},{id: 2,name: "jiuyer",inst: "oiuyt"}] },methods: {add_table: function(){var set = {id: this.id,name: this.name,inst : this.inst};this.table_data.push(set);// this.$broadcast("test", set); //这里,只是一个例子语法this.id = "";this.name = "";this.inst = "";}}});</script>上处举的两个例子,都可以点击这里测试,文件已经上传个人空间 vue父子组件通讯demo