组件的定义:

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。vuejs最大的特点就是采用组件来组合成页面,他将任何类型的应用的界面都抽象为一棵组件树。

说到底,组件就是我们封装的自定义的html元素,vue会根据模板编译成浏览器能够识别的html标签元素。所以vue的组件也跟我们标准的元素一样,在层级上,有父子组件,兄弟(平行)组件之分。不同层级的组件可以相互通信。下面我们就看不同组件之间的通信方式

1、子组件与父组件通信

当子组件想访问父组件的值的时候,我们可以通过子组件的props属性,将父组件的值传递给子组件

DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta charset="utf-8">
<!-- Always force latest IE rendering engine or request Chrome Frame -->
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<script type="text/javascript" src="https://unpkg.com/vue@2.2.1/dist/vue.min.js"></script>
<title>Cart</title>
</head>
<body class="checkout">
<div id="container">
<p>父组件</p>
<p>父组件obj.a的值是:{{obj.a}}</p>
<p>----------</p> <my-component :obj="obj"></my-component>
</div>
</body>
<script type="text/javascript">
//定义子组件 //父组件给子组件传值
var Child = {
template: '<div><span>子组件得到父组件obj.a的值是:{{obj.a}}</span></div>',
props : ['obj']
} var vm = new Vue({
el: "#container",
data: {
obj : {
a : 1,
b : 2
}
},
components: {
'my-component': Child
}
});
</script>
</html>

运行结果:

2、父组件与子组件通信

当子组件想修改父组件的值的时候,我们同样可以通过props属性来修改,但是注意的是,在这里父组件传递给子组件的数据对象必须是对象的引用,而不能是字面量

使用对象的引用来传递数据

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta charset="utf-8">
<!-- Always force latest IE rendering engine or request Chrome Frame -->
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<script type="text/javascript" src="https://unpkg.com/vue@2.2.1/dist/vue.min.js"></script>
<title>Cart</title>
</head>
<body class="checkout">
<div id="container">
<p>父组件</p>
<p>父组件obj.a的值是:{{obj.a}}</p>
<p>----------</p> <my-component :obj="obj"></my-component>
</div>
</body>
<script type="text/javascript">
//父组件给子组件传值,通过object
var Child = {
template: '<div><p>子组件A</p><span>子组件得到父组件obj.a的值是:{{obj.a}}</span><input type="button" @click="changeValue()" value="改变obj.a的值为3"></input></div>',
props : ['obj'],
methods : {
changeValue: function(){
this.obj.a = '3';
}
}
} var vm = new Vue({
el: "#container",
data: {
obj : {
a : 1,
b : 2
}
},
components: {
'my-component': Child
}
});
</script>
</html>

运行结果

这种方法是通过利用对象的引用指向同一个存储区域的方式来实现的。需要注意的是,这种方式虽然能够实现子组件修改父组件,但是我们在开发的过程中最好不要采用这种方式。因为我们总是希望的组件系统相对独立,这有利于组件之间的解耦,随意地在子组件这样的修改父组件的值,会破坏其独立性,导致项目难易维护。

官网推荐的方法是在子组件中通过v-on绑定自定义事件来实现

每个 Vue 实例都实现了事件接口,即:

使用 $on(eventName) 监听事件

使用 $emit(eventName) 触发事件

这个的运行跟我们常用的dom原生的事件机制是一样的。父组件注册好监听事件,当子组件需要对父组件进行操作的时候,调用触发函数,触发事件。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta charset="utf-8">
<!-- Always force latest IE rendering engine or request Chrome Frame -->
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<script type="text/javascript" src="https://unpkg.com/vue@2.2.1/dist/vue.min.js"></script>
<title>Cart</title>
</head>
<body class="checkout">
<div id="container">
<p>父组件</p>
<p>父组件obj.a的值是:{{obj.a}}</p>
<p>----------</p> <my-component :obj="obj" v-on:change="fatherChange"></my-component>
</div>
</body>
<script type="text/javascript">
//通过vm实例的on,emit方法
var Child = {
template: '<div><p>子组件A</p><span>子组件得到父组件obj.a的值是:{{obj.a}}</span></br><input type="button" @click="changeValue()" value="改变obj.a的值"></input></div>',
props : ['obj'],
methods : {
changeValue: function(){
console.log('aaa');
this.$emit('change',3)
}
}
} var vm = new Vue({
el: "#container",
data: {
obj : {
a : 1,
b : 2
}
},
components: {
'my-component': Child
},
methods: {
fatherChange: function(data){
this.obj.a = data;
}
}
});
</script>
</html>

这样做的好处是,我们的事件监听是在我们的父组件上面的,相对父组件做任何修改的逻辑都在父组件上实现,子组件只负责通知,这样就最大范围的解耦了两个组件之间的联系,增加了子组件的可复用性。

3、非父子组件的相互通信

在简单的场景下,使用一个空的 Vue 实例作为中央事件总线

这个空的vue实例作为一个媒介,来处理双方的通信

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta charset="utf-8">
<!-- Always force latest IE rendering engine or request Chrome Frame -->
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<script type="text/javascript" src="https://unpkg.com/vue@2.2.1/dist/vue.min.js"></script>
<title>Cart</title>
</head>
<body class="checkout">
<div id="container">
<p>父组件</p>
<p>----------</p> <child1></child1>
<child2></child2>
</div>
</body>
<script type="text/javascript"> //兄弟组件间的传递
var bus = new Vue();
var Child1 = {
template: '<div><p>子组件A的值为{{a}}</p><button @click="changeNum">改变值</button></div>',
data : function(){
return {
a : 1
}
},
mounted : function(){
var _that = this;
bus.$emit('calculateB',_that.a);
},
watch:{
a :function(){
var _that = this;
bus.$emit('calculateB',_that.a);
}
},
methods: {
changeNum : function(){
++ this.a;
}
}
} var Child2 = {
template: '<div><p>子组件B的值总是比组件A大3为{{a}}</p></div>',
data : function(){
return {
a : 0
}
},
created : function(){
var _that = this;
bus.$on('calculateB',function(data){
_that.a = data + 3;
})
}
} var vm = new Vue({
el: "#container", components: {
Child1 : Child1,
Child2 : Child2
},
methods: {
}
}); </script>
</html>

运行结果

以上的这些通讯方式可以实现我们任何的应用开发。但是有一个问题,当我们的项目越来越大,组件层级关系越来越复杂的时候,比如说我们的子组件又有子组件需要用到父组件的值,那么我们必须将父组件的值通过props一层一层传递下去,当层级只有2、3层的时候还好,如果我们层级有5层以上,这样一层一层传递导致我们的代码难以维护,同时出错的概率很大。为了解决这个问题,vue2.0提供了一个状态管理的方案vuex,具体可查看状态管理(http://cn.vuejs.org/v2/guide/state-management.html)

vue组件间的通信的更多相关文章

  1. vue 组件间的通信

    (1)props:用于父组件向子组件传递消息 使用方法: 在父组件中,使用子组件时,<Child v-bind:data="data"/>,通过v-bind把子组件需要 ...

  2. 第四节:Vue表单标签和组件的基本用法,父子组件间的通信

    vue表单标签和组件的基本用法,父子组件间的通信,直接看例子吧. <!DOCTYPE html> <html> <head> <meta charset=&q ...

  3. vue组件间通信六种方式(完整版)

    本文总结了vue组件间通信的几种方式,如props. $emit/ $on.vuex. $parent / $children. $attrs/ $listeners和provide/inject,以 ...

  4. Vue组件间通信6种方式

    摘要: 总有一款合适的通信方式. 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的 ...

  5. Vue组件间通信-Vuex

    上回说到Vue组件间通讯,最后留了一个彩蛋~~~Vuex.Vuex是另一种组件通讯的方法,这节来说说Vuex(store仓库). 首先Vuex需要安装,安装的方式有很多,在这里就不一一细说了.我是通过 ...

  6. vuejs单一事件管理组件间的通信

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Vue 组件间传值

    前言 Vue 作为现在比较火的框架之一,相信您在使用的过程中,也会遇到组件间传值的情况,本文将讲解几种 Vue 组件间传值的几种方法,跟着小编一起来学习一下吧! 实现 注意: 学习本文,需要您对 Vu ...

  8. Vue2不使用Vuex如何实现兄弟组件间的通信

    在一些正规的大型项目的企业级开发过程中我们一般会引入Vuex来对Vue所有组件进行状态管理,可以轻松实现各组件间的通信.但是有时候做做自己的小项目,没有必要使用Vuex时,如何简单的实现组件间的通信? ...

  9. Vue组件间通信方式到底有几种

    1. 前言 Vue的一个核心思想就是组件化.所谓组件化,就是把页面拆分成多个组件 (component),每个组件依赖的 CSS.JavaScript.模板.图片等资源放在一起开发和维护.组件是资源独 ...

随机推荐

  1. 《Spring1之第七次站立会议》

    <第七次站立会议> 昨天:我把自己项目工程里的服务器端界面进行了优化和完善. 今天:我查找了关于实现视频功能的相关代码. 遇到的问题:找到的都是基于C#的相关代码,很难找到用java实现的 ...

  2. 安卓开发神器vysor+adb wifi

    准备: 1.vysor需要FQ从google应用商店下载,装在google上,目前知道的免费的vysor的作用是电脑显示手机屏幕并且能操控手机. 步骤:FQ后就能下载了,FQ方法不赘述.

  3. 使用myeclipse2014整合ss2h

    使用myeclipse2014整合ssh 新建一个webproject 创建过程中注意选择生成web.Xml   先添加struts2的能力 选择都添加过滤器的选项 Core dojo Dwr spr ...

  4. echart 插件实现全国地图

    最近的项目要用到一个能展现全国地图的功能,并且全国各个省份显示的颜色不同,点击省份后会返回省份名称.经过反复的查找最终确定了echart这个插件,最后的成果还不错,在这里写下来希望对大家有所帮助.话不 ...

  5. C++课程 second work _1025

    传送门 Problem 题目不是特别难,只是跪在了最后一个测试点(已解决). 最后一个测试点= = 无效节点...无力ing

  6. week2:个人博客作业

    1.这周写程序感想: 昨天差不多,也是这个时候看些的程序,写了4个小时程序,感触颇多.昨日,原打算,就完成程序就吧这个随笔写完结果,由于各种原因,没写一直拖到现在.就做昨天写的程序,本身题目很简单,主 ...

  7. [转帖]认识固态:SSD硬盘内外结构解析

    认识固态:SSD硬盘内外结构解析 来自: 中关村在线 收藏 分享 邀请 固态硬盘(Solid State Drive),简称固态盘(SSD),是用固态电子存储芯片阵列而制成的硬盘,由控制单元和存储单元 ...

  8. ACM数论之旅5---数论四大定理(你怕不怕(☆゚∀゚)老实告诉我)

    (本篇无证明,想要证明的去找度娘)o(*≧▽≦)ツ ----------数论四大定理--------- 数论四大定理: 1.威尔逊定理 2.欧拉定理 3.孙子定理(中国剩余定理) 4.费马小定理 (提 ...

  9. 再谈MySql索引

    一.索引简介 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 索引分单列索引(主键索引.唯一索引.普通索引)和组合索引.单列索引,即一个索引只包含单个列 ...

  10. Mac突然连不上WiFi

    标签(空格分隔): 杂七杂八的问题 从昨晚开始,Mac突然连不上WiFi了,人又在图书馆,上不了网好焦急.于是搜了很多方法,也不知是哪个起作用了,反正现在可以了. 步骤一 打开"Finder ...