组件的定义:

组件(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. Java每日编程day2

    Java每日编程day2 第一题 package com.pcx.day2; /* * 九九乘法表并逆序 */ public class JiuJiu { public static void mai ...

  2. ASP.NET MVC 1.0 参考源码索引

    http://www.projky.com/asp.netmvc/1.0/System/Web/Mvc/AcceptVerbsAttribute.cs.htmlhttp://www.projky.co ...

  3. PHP 多进程开发

    pcntl_fork(); https://blog.csdn.net/wujiangwei567/article/details/77006724 https://blog.csdn.net/qq_ ...

  4. 9th 学习博客:使用Codebloks实现C++的图形化界面

    使用开发工具codeblocks,添加ResEdit.exe这个控件,可以很方便地进行图形化编辑,这是在网上找得教程,实现的是最基本的在对话框内添加按钮,并实现单击响应在控制台输出相应的文字. mai ...

  5. HTML与URL两种录制模式分析(转)

    如何选择两种模式? 1.基于浏览器的应用程序推荐使用HTML-Based Script. 2.不是基于浏览器的应用程序推荐使用URL-Based Script. 3.如果基于浏览器的应用程序中包含了J ...

  6. 2018最新Web前端经典面试试题及答案

    javascript: JavaScript中如何检测一个变量是一个String类型?请写出函数实现 typeof(obj) === "string" typeof obj === ...

  7. Json的JsonValueProcessor方法

    将对象转换成字符串,是非常常用的功能,尤其在WEB应用中,使用 JSON lib 能够便捷地完成这项工作. JSON lib能够将Java对象转成json格式的字符串,也可以将Java对象转换成xml ...

  8. pyqt5 eric6

    1 安装Anaconda3 2 python环境变量改为Anaconda3中python 3 pip安装pyqt5 ,pip安装pyqt5-tool 其中tool中包含eric6 ui文件必须使用的d ...

  9. poj 1966(顶点连通度)

    题意:给出一个n个节点和m条边的图,求该图的顶点连通度. 分析: 顶点连通度的求解可以转换为网络最大流问题. (1)原图G中的每个顶点v变成网络中的两个顶点v‘和v’‘,顶点v’至v''有一个条弧(有 ...

  10. UVAlive3211_Now or later

    白书上的例题. 每种航班可以选择两种时间降落,如果想任意航班降落时间差的最小值最大,应该如何安排? 二分时间,如果两个时间只差小于当前枚举的时间,说明这条边不可选,可以根据2sat的方法构图. 然后判 ...