组件的定义:

组件(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. Mininet-Wifi 多接入点(Access Point)实验

    实验简介  这个实验来自Mininet-Wifi用户手册.在本实验中,我们会创建一个有三个AP的线式拓扑,并有三个站点(station)与每个AP通过无线相连.将通过这个时间简单演示一些Mininet ...

  2. Alpha版本冲刺(六)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...

  3. js如何判断一个值是不是Array类型

    本来判断一个对象类型用typeof是最好的,不过对于Array类型是不适用的可以使用 instanceof操作符var arrayStr=new Array("1","2 ...

  4. 全选练习-原生版和jQuery

    今天来做一些练习,做全选练习 原生版的实现: <!DOCTYPE html> <html> <head> <meta charset="UTF-8& ...

  5. beta 发布的相关评论

    1. 礼物挑选小工具 飞天小女警      这个项目的创意独具匠心,贴近实际,令人耳目一新,网站的页面也是玫红色的,配色让人感到很温馨,对礼物的筛选方式很有趣,使用的记录特殊日子的方法来提醒自己挑选礼 ...

  6. 动态语句SQL语句写法

    /*************************************************************************************************** ...

  7. Spring Cloud之Eureka服务注册与发现

    解决什么问题 ➟阐述微服务以及服务注册发现的部分概念 ➟阐述Eureka服务注册与发现的部分原理及细节 为什么需要服务中心 过去,每个应用都是一个CPU,一个主机上的单一系统.然而今天,随着大数据和云 ...

  8. Caffe使用step by step:faster-rcnn目标检测matlab代码

    faster-rcnn是MSRA在物体检测最新的研究成果,该研究成果基于RCNN,fast rcnn以及SPPnet,对之前目标检测方法进行改进,faster-rcnn项目地址.首先,faster r ...

  9. vue & button & refs & click & bug

    vue & button & refs & click & bug $refs.btn.click() ??? vue & refs $refs.btn.$em ...

  10. js遍历数组和遍历对象

    可以用for in来遍历对象,具体内容如下: <script type="text/javascript">             var objs = {      ...