Vue.js 父子组件通讯

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">&nbsp;</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的路上共勉

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值