组件的定义:

组件(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. "私人助手"NABCD分析

    ---恢复内容开始--- 团队开发项目“私人助手”需求分析NABCD模型: (1)N(Need需求):“私人助手”解决了几类人遇到非常多的事情,非常繁琐,“私人助手”为用户解决这个问题,让用户的工作更 ...

  2. window 窗口编辑

    package com.chuangkohua; import java.awt.FileDialog; import java.awt.FlowLayout; import java.awt.Fra ...

  3. 第二次作业<1>

    1001.A+B Format (20) ac代码 1. 解题思路 先求和,再输出. 答案区间为-2,000,000至2,000,000,将答案分为三个区段分类讨论.虽然觉得很烦但是想不出更好的方法. ...

  4. HDU 3092 Least common multiple 01背包

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3092 Least common multiple Time Limit: 2000/1000 MS ...

  5. The last time the sprint(最后一个冲刺)

    经过一两个月的努力,我们终于是做出来了一点东西,从一开始接触这个项目开始,从完全不知道怎么去入手到跌跌碰碰,再到现在可以拿出来一点东西给别人看,我觉得很开心,或许我的这个成品在别人眼中并不算是什么,但 ...

  6. 学习率(Learning rate)的理解以及如何调整学习率

    1. 什么是学习率(Learning rate)?   学习率(Learning rate)作为监督学习以及深度学习中重要的超参,其决定着目标函数能否收敛到局部最小值以及何时收敛到最小值.合适的学习率 ...

  7. Gradle入门(2):构建简介

    基本概念 在Gradle中,有两个基本概念:项目和任务.请看以下详解: 项目是指我们的构建产物(比如Jar包)或实施产物(将应用程序部署到生产环境).一个项目包含一个或多个任务. 任务是指不可分的最小 ...

  8. Java 多生产者消费者问题

    /* 生产者,消费者.   多生产者,多消费者的问题. if判断标记,只有一次,会导致不该运行的线程运行了.出现了数据错误的情况. while判断标记,解决了线程获取执行权后,是否要运行!   not ...

  9. 学术诚信与职业道德——《构建之法》P384~391读后感

    程序本身没有伦理和职业道德, 但是程序员和软件企业要有,因为程序员明白伦理道德的存在. 对于刚刚经历被不负责队友抛下的经历,对此很有感触,软件工程师除了遵守任务做事,也要考虑道德上.责任上的事情. 就 ...

  10. [转帖]IBM POWER9 E950 and E980 Servers Launched

    IBM POWER9 E950 and E980 Servers Launched https://www.servethehome.com/ibm-power9-e950-and-e980-serv ...