Vue.js 父子组件通讯开发实例
作者:wxc_niuniu
vue.js,是一个构建数据驱动的 web 界面的库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。(这是官方的一个解释!)
小编没使用过angularjs,也没使用过react.js,不能详细的说明三者的区别,想了解的话,在官方有一个分析,请点这里查看
小编从业前端开发也有了一年多的时间,刚开始的时候,前端开发展现的技术太多,小编有心无力,兼顾不过来,经过了解之后,还是选择了学原生js基础兼并jquery的学习上路。小编使用vue.js,也是因为业务的需求,为什么不选择angularjs,其实就是同时不能抛弃jquery,vue.js和jquery可以完美的兼容,因为这个项目,小编也是苦逼了好长一段时间,不断的加班和学习,避免项目的开发时间增加,废话不多说,下面开始一些小编的vue的学习总结,写得不好,也不要见怪哈,写文一直是我的短板。。。。
父链 小编这里,就是vue的实例,作为父链
子组件可以通过 this.parent它的父亲组件。根实例的可以使用this.root 访问它。父有一个数组 this.children,它所有元素;当然,在项目中,我们的组件不可以只有一个或者两个,当组件多了的时候,我们是难以记得children中该组件的位置的,我们可以利用 v-ref 的指令,给我们的组件建立一个钩子,这个钩子,就是我们的其他组件访问该组件时的索引
//这是我的一个组件 <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_msg this.msg.push(msg); } }, methods: { add: function(msg){ this.msg.push(msg); } } }); </script>
看完这段代码,相信大家都知道$dispatch()的冒泡的用法了,其实,就是这么点东西,里面有两个参数,第一个参数,就是父组件监听子组件events对象里面的一个方法名,两者要一致;第二个参数,就是子组件更新的数据,同时也是传递给给父组件要同步更新的数据,然后父组件就用这个参数来进行相应的操作
//$broadcast()方法的用法和$dispatch()的用法是一样的,不一样的是,event对象是在子组件里面创建,相反触发的函数在父组件;这里要说的是,如果子组件的数据完全依赖于父组件的数据,那么,则不需要用通说事件传递的方式,只需要通过props获取父组件的数据,绑定到子组件身上就可以了
<!-- 组件通讯二 $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
当写到这里的时候,回头看了一下,自己写的内容,貌似写得有点乱,真是汗颜啊!很久之前就想过写博客,建立自己的笔记库,只是以前尝试写的时候,真是无法下手如何去写,最近,下定决心,不管写的怎么样,也坚持去写,万一哪天自己的文笔突然变得好起来了呢!
vue父子组件通讯,其实应用并不是很难,它其实也是提供了相应的api接口监听,实际的项目应用该如何操作变化,还是得需要我们自己写,重点,还是得要提高我们的js水平,毕竟,复杂的web应用越来越多!希望,喜欢前端的同学们都能在js的路上共勉.