组件的定义:

组件(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. BETA随笔6/7

    前言 我们居然又冲刺了·六 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 过去两天完成了哪些任务 新方案代码比之前的更简单,但是对场景的要求相应变高了,已经实现,误差感人 代码 ...

  2. c++第七次作业____最后的总结

    先言: 在这过程中学到: 第二次作业Github的使用 第四次作业计算器的计算 ps:表达式处理以及计算 第五次作业文件的处理问题 第六次作业界面的设计 总结: 1.这学期的计算器,做的有点匆忙,偶尔 ...

  3. Android笔记-1

    1.点击按钮出现小窗口(响应事件) 配置方式: Activity_main.xml文件中:<Button (输入)android: onClick=”test1” /> MainActiv ...

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

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

  5. mac下使用marsedit写博客

    在Windows习惯了使用Windows live write写好博客,然后发布上去,到了mac下,发现了一个很好的替代品  MarseEdit 下载安装后,打开出现如下解码,选择 I already ...

  6. jmeter 常用内置变量

    1. vars   API:http://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html vars.get(& ...

  7. 通过session 怎么防止表单的重复提交!

    1.在提交表单的时候使用隐藏域: String tokenValue=new Date().getTime(); <input type="hidden" name=&quo ...

  8. 我的虚拟机中的 centOS 连不了网了

    网上的办法试过了,查看虚拟机的网络配置,是 NET的, 也 cd 到/etc/sysconfig/network-script/ifcfg-eth0 里面看了,onboot 本来就是 yes,要不然我 ...

  9. hdu6447 YJJ's Salesman

    这个题意和数据范围一看就是离散化之后树状数组优化DP.给的"从左下方走上去才能拿到收益"的性质其实可以当成"必须从横纵坐标严格比某个点小的地方转移过来".1A了 ...

  10. Robot Framework 的安装配置和简单的实例介绍

    Robot Framework 介绍 Robot Framework 是一款基于 Python 的功能自动化测试框架.它具备良好的可扩展性,支持关键字驱动,可以同时测试多种类型的客户端或者接口,可以进 ...