vue组件详解(三)——组件通信

组件之间通信可以用下图表示:

组件关系可分为父子组件通信、兄弟组件通信、跨级组件通信。

一、自定义事件

当子组件需要向父组件传递数据时,就要用到自定义事件。

子组件用$emit ()来触发事件,父组件用$on()来监昕子组件的事件。

父组件可以直接在子组件的自定义标签上使用v-on 来监昕子组件触发的自定义事件,如:

        <div id="app9">
            <p>总数:{{total}}</p>
            <my-component9 @add="getTotal" @cut="getTotal"></my-component9>
        </div>
Vue.component(‘my-component9‘,{
    template: ‘<div>‘ +
    ‘               <button @click="increase">+1</button>‘ +
    ‘               <button @click="reduce">-1</button>‘ +
            ‘</div>‘,
    data: function(){
        return {
            count: 0
        }
    },
    methods:{
        increase: function(){
            this.count++;
            this.$emit(‘add‘,this.count)  //广播的事件名和数据
        },
        reduce: function(){
            this.count--;
            this.$emit(‘cut‘,this.count)  //广播的事件名和数据
        }
    }
});

var app9 = new Vue({
    el: ‘#app9‘,
    data:{
        total: 0
    },
    methods:{
        getTotal: function(count){
            this.total = count;
        }
    }
});

二、使用v-model

Vue2 .x 可以在自定义组件上使用v-model 指令,直接看一个事例:

        <div id="app10">
            <p>总数:{{total}}</p>
            <my-component10 v-model="total"></my-component10>  //这个地方v-model实际是一个语法糖,可以直接理解为接收到广播input里面的数据(this.total=count)。
        </div>
Vue.component(‘my-component10‘,{
    template: ‘<div>‘ +
                ‘<button @click="increase">+1</button>‘ +
                ‘<button @click="reduce">-1</button>‘ +
              ‘</div>‘,
    data: function(){
        return {
            count: 0
        }
    },
    methods:{
        increase: function(){
            this.count++;
            this.$emit(‘input‘,this.count)  //注意这个地方,广播的事件名称为特殊的input
        },
        reduce: function(){
            this.count--;
            this.$emit(‘input‘,this.count)  //注意这个地方,广播的事件名称为特殊的input
        }
    }
});

var app10 = new Vue({
    el: ‘#app10‘,
    data:{
        total: 0
    }
});

v-model 还可以用来创建自定义的表单输入组件, 进行数据双向绑定,例如:

        <div id="app11">
            <p>总数:{{total}}</p>
            <my-component11 v-model="total"></my-component11>
            <button @click="reduce">-1</button>
        </div>
Vue.component(‘my-component11‘, {
    props: [‘value‘],  //使用v-model的表单组件时,父组件通过value来进行传值
    template: ‘<input :value="value" @input="updateValue">‘,
    methods: {
        updateValue: function(event){
            this.$emit(‘input‘, event.target.value);
        }
    }
});

var app11 = new Vue({
   el: ‘#app11‘,
   data:{
      total: 0
    },
    methods:{
        reduce: function(){
            this.total--
        }
    }
});

父组件的total发生变化时,会通过传递value值,影响子组件input中的value值,而子组件改变自己input中的value值,又会广播给父组件,影响父组件中的total值。

实现这样一个具有双向绑定的v -model 组件要满足下面两个要求:

?接收一个value 属性。
? 在有新的value 时触发input 事件。

三、非父子组件通信

在Vue . 2.x 中, 推荐使用一个空的Vue 实例作为中央事件总线( bu s ),也就是一个中介。

直接看一个事例:

        <div id="app12">
            <p>{{message}}</p>
            <my-component12></my-component12>
        </div>
var bus = new Vue();

Vue.component(‘my-component12‘,{
   template: ‘<button @click="updateMessage">传递事件信息</button>‘,
    methods: {
        updateMessage: function(){
            bus.$emit(‘updateMessage‘,‘更新我的组件信息‘);   //利用中介bus传播事件
        }
    }
});

var app12 = new Vue({
   el: ‘#app12‘,
   data:{
        message: ‘‘
    },
    mounted: function(){
        var _this = this;   //这一步赋值必须有
        bus.$on(‘updateMessage‘,function(data){     //利用中介bus接收事件
            _this.message = data;
        })
    }
});

在app 初始化时,也就是在生命周期mounted 钩子函数里监听了来自bus 的事件updateMessage(mounted挂载这一步相当于在两个组件直间提前安排了一个中介,当两个组件通信时,就可以通过该中介相互传递消息了) ,

而在组件my-component12中,点击按钮会通过bus 把事件updateMessage发出去,此时app 就会接收到来自bus 的事件,进而在回调里完成自己的业务逻辑。

这种方法巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级,而且Vue 1.x 和Vue 2.x 都适用。

四、父链与子组件索引

除了中央事件总线bus 外,还有两种方法可以实现组件间通信:父链和子组件索引。

在子组件中,使用this.$parent 可以直接访问该组件的父实例或组件,父组件也可以通过this.$children 访问它所有的子组件,而且可以递归向上或向下无线访问, 直到根实例或最内层的组件。

4.1父链

        <div id="app13">
            <p>{{message}}</p>
            <my-component13></my-component13>
        </div>
Vue.component(‘my-component13‘,{
    template: ‘<button @click="updateMessage">通过父链直接修改数据</button>‘,
    methods: {
        updateMessage: function(){
            this.$parent.message = ‘来自组件my-component13的内容‘  //通过this.$parent直接修改父组件的内容
        }
    }
});

var app13 = new Vue({
    el: ‘#app13‘,
    data:{
        message: ‘‘
    }
});

尽管V ue 允许这样操作,但在业务中, 子组件应该尽可能地避免依赖父组件的数据,更不应该去主动修改它的数据,因为这样使得父子组件紧藕合,理想情况下,只有组件自己能修改它的状态。

4.2 子组件索引

当子组件较多时, 通过this.$children 来一一遍历出我们需要的一个组件实例是比较困难的,尤其是组件动态渲染时,它们的序列是不固定的。Vue 提供了子组件索引的方法,用特殊的属性ref来为子组件指定一个索引名称。

        <div id="app14">
            <p>{{message}}</p>
            <my-component14 ref="com14"></my-component14>
            <button @click="handleRef">通过ref获取子组件实例</button>
        </div>
Vue.component(‘my-component14‘,{
    template: ‘<div>子组件</div>‘,
    data: function(){
        return {
            message: ‘子组件内容‘
        }
    }
});

var app14 = new Vue({
    el: ‘#app14‘,
    data:{
        message: ‘‘
    },
    methods: {
        handleRef: function(){
             this.message = this.$refs.com14.message;   //通过$refs获取子组件实例
        }
    }
});

在父组件模板中,子组件标签上使用ref 指定一个名称,井在父组件内通过this.$refs 来访问指定名称的子组件。

$refs 只在组件渲染完成后才填充,并且它是非响应式的. 它仅仅作为一个直接访问子组件的应急方案,应当尽量避免在模板或计算属性中使用$refs。

原文地址:https://www.cnblogs.com/chaixiaozhi/p/8746823.html

时间: 2024-10-04 11:53:54

vue组件详解(三)——组件通信的相关文章

vue.js基础知识篇(6):组件详解

第11章:组件详解 组件是Vue.js最推崇也最强大的功能之一,核心目标是可重用性. 我们把组件代码按照template.style.script的拆分方式,放置到对应的.vue文件中. 1.注册 Vue.js的组件注册分为全局注册和局部注册. 全局注册使用Vue.component方法.第一个参数是组件名字,第二个参数是组件的构造函数,要么是function,要么是object. <!DOCTYPE html> <html lang="en"> <hea

Android 四大组件 详解

[置顶] Android四大组件详解 分类: Android四大组件2013-02-09 16:23 19411人阅读 评论(13) 收藏 举报 Android开发 注:本文主要来自网易的一个博主的文章,经过阅读,总结,故留下文章在此 Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity : 应用程序中,一个

Android组件系列----Activity组件详解

[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3924567.html 联系方式:[email protected] [正文] 注:四大组件指的是应用组件:Activity.Service.BroadcastReceiver.ContentProvider:之前的控件指的是UI组件. 博文目录: 一.Activity简介 二.Activity的状

Tomcat系列之服务器的安装与配置以及各组件详解

Tomcat系列之服务器的安装与配置以及各组件详解 大纲 一.前言 二.安装与配置Tomcat 三.Tomcat 目录的结构 四.Tomcat 配置文件 注,本文的测试的操作系统为CentOS 6.4 x86_64,软件版本为jdk-7u40.apache-tomcat-7.0.42.博文中的所有软件请到这里下载:http://yunpan.cn/QGBCLwrZnpLMS. 一.前言 在上一篇博文中我们主要讲解的Tomcat的基础知识以及相关的Java知识,对于不怎么清楚的博友可以参考一下:h

Android中Intent组件详解

Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件.Intent本身是定义为一个类别(Class),一个Intent对象表达一个目的(Goal)或期望(Expectation),叙述其所期望的服务或动作.与动作有关的数据等.Android则根据此Intent对象之叙述,负责配对,找出相配的组件,然后将 Intent对象传递给所找到的组件,Android的媒婆任务就完成了. 在Google Doc中是这样描述Intent的(摘自Android中文翻译组)当接收到ContentR

基于jQuery的TreeGrid组件详解

一.TreeGrid组件相关的类 1.TreeGrid(_config) _config:json格式的数据,组件所需要的数据都通过该参数提供. 2.TreeGridItem(_root, _rowId, _rowIndex, _rowData) _root:显示组件实例的目标容器对象. _rowId:选中行的id. _rowIndex:选中行的索引. _rowData:json格式的行数据. 二._config参数详解 id:组件实例的id. width:组件实例的宽度. renderTo:用

[转]详解C#组件开发的来龙去脉

C#组件开发首先要了解组件的功能,以及组件为什么会存在.在Visual Studio .NET环境下,将会有新形式的C#组件开发. 组件的功能 微软即将发布的 Visual Studio .NET 将使程序开发人员获得一个集成开发环境,它不但为开发传统的 C/C++ 应用程序,而且也为令人振奋的Microsoft .NET 组件提供了丰富的工具.这些以管理代码编写.在通用语言运行时构建的组件向开发人员提供了一个全新的混合开发环境,即象 Microsoft Visual Basic 一样容易,而同

ionic中文详解CSS组件

ionic组件 本来不想写这个的,因为毕竟官网已经列的很详细了css component,国内的网络由于种种原因,有时候右边并不会显示一个手机框用于展示效果.我这里将一些相关组件的介绍合在一起,给出综合例子和显示效果,方便自己查阅.另外官网的JS API介绍文档有问题,国内访问不能跳转,请参考我的另一篇ionic中文javascript API. 教程索引:(持续更新中...)ionic中文教程 转载请注明出处:http://www.haomou.net/2014/08/09/2014_ioni

Vue 实例详解与生命周期

Vue 实例详解与生命周期 Vue 的实例是 Vue 框架的入口,其实也就是前端的 ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个 Vue 实例生成.编译.挂着.销毁等过程进行 js 控制. Vue 实例初始化的选项配置对象详解 前面我们已经用了很多次 new Vue({...})的代码,而且 Vue 初始化的选项都已经用了data.methods.el.computedd等,估计您看到这里时,应该已经都明白了他们的作

关于Vue.use()详解

关于Vue.use()详解 问题 相信很多人在用Vue使用别人的组件时,会用到 Vue.use() .例如:Vue.use(VueRouter).Vue.use(MintUI).但是用 axios时,就不需要用 Vue.use(axios),就能直接使用.那这是为什么呐? 答案 因为 axios 没有 install. 什么意思呢?接下来我们自定义一个需要 Vue.use() 的组件,也就是有 install 的组件,看完之后就明白了. 定义组件 生成模版 vue init webpack-si