vue中比较重要的就是组件了。而组件随处可复用的特性,使得组件通信非常重要。那么组件之间通讯方式有哪些呢?

第一种:父子组件通讯:

如果是 html页面 中全局注册的组件 和 实例中局部注册的组件

HTML:

<div id="box"></div>

JS:

Vue.component('child',{
name:'child',
props:{
msg:{
type:String,
require:true
}
},
template:`
<div id='getChild'>
<h3>我是child组件</h3>
<p>{{msg}}</p>
<button @click='getParentVal'>点击获取父组件内容</button>
<button @click='sendVal'>向父组件传递内容</button>
</div>
`,
data:function(){
return {
childVal:'我是子组件中的数据'
}
},
methods:{
//这里是获取父组件中的属性或方法
getParentVal:function(){
console.log(this.$parent.age)
},
//这个是向父组件传递指定的内容
sendVal:function(){
this.$emit('sendChild',{
mssg:'我是子组件$emit传过来的内容'
})
}
}
})
Vue.component('myParent',{
name:'parent',
template:`
<div>
<button @click='getVal'>点我获取子组件内容</button>
<child :msg='parentVal' ref='getChild' @sendChild='getSendChild'></child>
</div>
`,
data:function(){
return {
parentVal:'我是parent组件传过来的值',
age:666
}
},
methods:{
//这个是获取子组件的属性或方法
getVal:function(){
console.log(this.$refs.getChild.childVal)
},
//这个是获取子组件通过emit传递过来的内容
getSendChild:function(res){
console.log(res)
}
}
}) new Vue({
el:'#box',
  //这里局部注册父组件
  template:`
    <my-parent></my-parent>
  `
})

注意事项:

1) 组件需要先注册才能使用,注册又分 局部注册 和 全局注册。局部注册需要在实例里面的template声明组件的内容,全局注册即如上例一样。

2) 组件名支持驼峰,小写,大写,横线(xxx-xxx)的写法。但是在使用组件的时候,如果是驼峰的写法,则需要写成横线的形式。如上面 组件名是myParent ,那么使用的时候 就必须是 <my-parent></my-parent> 。

3) 父组件可以获取子组件的数据和方法,通过在引用子组件的时候定义 ref='自定义名称'  ,然后在子组件的template中最外层节点,定义一个id值,然后父组件中使用  this.$refs.自定名称.子组件数据  。就如同上例点击获取子组件数据一样。或者不加ref,直接使用 this.$children[第几个子组件].子组件数据。

4) 子组件可以获取父组件的数据和方法,在子组件中使用 this.$parent.子组件数据。

5) 子组件通过 $emit('自定义名称',数据) 来达到向父组件传递指定的数据,类似 jQuery 的 trigger 。

6) 父组件通过 实例.$on('对应emit定义的名称',function(res){}) 或者  在引用子组件的时候   <child @对应emit定义的名称='自己定义的函数名'></child> ,然后在methods中指定  自己定义的函数名  获取到的  res 就是子组件传过来的值。

7) template 里面的内容 可以用  ` `  就是键盘上 esc 下面的那个波浪键 在英文状态下打出来的内容  ,这样就不用向es5一样用 + 加号和 ' ' 引号来合并成字符串了。

8) props 中命名方式 不支持 xxx-xxx 这种横线的格式,支持驼峰,小写。如果props中是驼峰的命名方式,那引用组件的时候就要写成对应的横线方式,例如props:[getPhone]   那么<child get-phone='xxx'></child> ,如果绑定的是动态值也是一样的写法<child :get-phone='xxx'></child>  。原因:由于html不区分大小写的特性,所以没法对应组件中的驼峰名称。

9) 为什么组件中的data必须是函数,然后返回对象?因为组件是用于复用的,彼此之间的数据一定要是唯一的。所以如果data就是一个对象,那么由于对象是引用类型,不同地方引用同一个对象,并不是引用的值,而是引用的对象的地址,所以某一处修改之后,其它的也会跟着变化,这样就不能达到数据唯一的目的。而使用函数再返回一个对象,每个对象的地址都是不同的,就能保证每次都是一个新的对象。

10)props验证方式的写法可以查看官网,里面的prop验证

11) template 里面的内容必须只有一个根元素。

如果是 .vue 这种单文件模块 的组件

这种方式和 html 页面 中注册组件有稍许的不一样。

//child 组件
<template>
<div>
xxxx
</div>
</template>
<script>
export default {
props:[],
data:function(){}
}
</script>
<style> </style>
//parent 组件
<template>
<div>
<childComponent></childComponent>
//如果注册的时候不重命名的话就可以使用<child></child>
</div>
</template>
<script>
import child from 'xxx'
export default {
data:function(){},
components:{
'childComponent':child //如果不重名的话可以直接是{child}
},
data:function(){}
}
</script>
<style> </style>

说明:

1) 每个 .vue单文件组件模块,都需要在 template 中声明组件的内容,并且也只有一个根元素。

2) 在script 里面 需要 export default 组件注册的必须内容,例如props,data,mthods等。

3) 在需要引入组件的页面  import  自定义组件名称  from  'xxx' 。组件的名称自定义,支持大写,小写,驼峰,横线(xxx-xxx)。

4) import 组件之后,还需要在components中注册组件。注册的时候也可以重命名组件名称。

5) 除了上面的区别,其它的就没什么区别了,组件的通讯也和上面 html页面中组件通讯一样的处理方式。

第二种:非父子组件之间的通讯。

在 html 页面中,注册方式与父子组件无差别,也是全局注册和局部注册。

HTML:

<div id="box"></div>

JS:

//全局注册mine组件
Vue.component('mine',{
template:`
<div>
我是mine组件
<button @click='sendToBrother'>点击向brother组件发送内容</button>
</div>
`,
data:function(){
return {
name:'mine',
sex:'male'
}
},
mounted:function(){
//接收mine组件传过来的内容
transfer.$on('brotherVal',function(res){
console.log(res)
})
},
methods:{
//向brother组件传递内容
sendToBrother:function(){
transfer.$emit('mineVal',this.name)
}
}
})
//全局注册brother组件
Vue.component('brother',{
template:`
<div>
我是brother组件
<button @click='sendToMine'>点击向mine组件发送内容</button>
</div>
`,
data:function(){
return {
name:'brother',
age:666
}
},
mounted:function(){
//接收mine组件传过来的内容
transfer.$on('mineVal',function(res){
console.log(res)
})
},
methods:{
//向mine组件发送内容
sendToMine:function(){
transfer.$emit('brotherVal',this.name)
}
}
}) //这是最重要的一步,定一个空的实例对象。
var transfer=new Vue(); new Vue({
el:'#box',
data:{},
//局部注册两个组件
template:`
<div>
<mine></mine>
<brother></brother>
</div>
`
})

说明:

1) 主要的就是通过一个 中间实例对象来实现 非父子组件之间的通讯

2) 还是通过 $emit() 来发送内容 , $on() 来接收传递过来的内容 ,只是使用这两个方法的对象并不是 this 而是 一个空的实例对象。要注意 $on 和 $emit 中的事件名要对应

3) 不一定是mounted的时候才去接收传过来的内容,created的时候也是可以的。应该是只要生命周期里,数据初始化完成之后都行。

4) 具体是什么原理,我不清楚。也感觉没必要去搞懂

如果是 .vue 这种单文件模块 的组件

这种方式和 html 页面 中注册组件有稍许的不一样。而且通讯的方式也有一点差距。

第一步:需要中间实例对象,于是新建一个  transfer.js

import Vue from 'vue'
export default new Vue();

第二步:需要传值的页面,引入这个js

//mine 组件
<template>
<div>
<button @click='sendToBrother'>点我向brother组件发送内容</button>
</div>
</template>
<script>
import transfer from 'transfer.js的路径'
export default {
data:function(){
return {}
},
methods:{
sendToBrother:function(){
transfer.$emit('sendVal','这是mine组件传过来的值')
}
}
}
</script>
<style> </style>
//brother 组件
<template>
<div>
xxx
</div>
</template>
<script>
import transfer from 'transfer.js的路径'
export default {
data:function(){
return {}
},
mounted:function(){
transfer.$on('sendVal',function(res){
console.log(res)
})
}
}
</script>
<style> </style>

第三步:在引用这两个组件的地方,注册这两个组件。

//引入组件的页面
<template>
<div>
<mine></mine>
<brother></brother>
</div>
</template>
<script>
import mine from 'mine组件的路径';
import brother from 'brother组件的路径'
export default {
data:function(){
return {}
},
components:{ mine ,brother },
}
</script>
<style> </style>

说明:

1) 实现的方式还是差不多的 , 都是 $on 接收内容   $emit 发送内容。

2) 只是中间实例对象需要添加到一个 js 中。然后两个组件页面都需要引入。

3) 这种通过中间实例对象的方式,也可以用于  父子、祖孙 等关系的组件通讯。

上面的通讯方式是最常见的。但是在组件通讯这块,vue 2.4 版本又增加了 inheritAttrs、attrs和listeners 。这三个的用法,后面再找个机会补上。


如果遇到 父级组件需要传给 子级组件的props值 是通过  ajax  异步请求  传入的  。那么,在子组件的生命周期中获取该props内容是获取不了的。就算是在mounted 中也是获取不了的。

这个时候的解决办法是:

<childComponent  :sendVal='getval'  v-if='getval'></childComponent>

一定要加一个  v-if ,这样才能在 子组件的 mounted 中获取到该值。这个地方是把我坑惨的。。。网上有推荐说如果是数组,可以使用  v-if = 'getval.length' 。这完全没必要,而且有可能还会报错,因为getval的值有可能还没返回来,再去取length肯定会报错。 如果是布尔值的话,更要注意点。

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

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

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

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

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

  3. vue组件间通信

    组件间通信(父子,兄弟) 相关链接\组件通信http://www.cnblogs.com/xulei1992/p/6121974.html 学习链接Vue.js--60分钟快速入门http://www ...

  4. vue组件间通信子与父

    二.组件间通信(子组件传值给父组件) 通过事件的方式来完成数据的传输. ①在父组件中 定义一个方法,用来接收子组件所通过事件传来的值 methods:{ recvMsg:function(msg){ ...

  5. Vue组件间通信-Vuex

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

  6. Vue组件间通信:一个例子学会Vue组件-Vue.js学习总结)(转载)

    详情请点击 http://www.jianshu.com/p/9ad1ba89a04b

  7. 聊聊Vue.js组件间通信的几种姿势

    写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出. 文章的原地址:https://github.com/a ...

  8. VUE组件如何通信

    Vue父子组件如何通信? 子组件通知父组件(调用父组件方法) 在父组件使用 on(eventName)监听事件,在子组件使用emit(eventName) 触发事件 : 父组件通知子组件(调用子组件方 ...

  9. vue-learning:31 - component - 组件间通信的6种方法

    vue组件间通信的6种方法 父子组件通信 prop / $emit 嵌套组件 $attrs / $liteners 后代组件通信 provide / inject 组件实例引用 $root / $pa ...

  10. 【Vue】利用父子组件间通信实现一个场景

    组件间通信是组件开发的,我们既希望组件的独立性,数据能互不干扰,又不可避免组件间会有联系和交互. 在vue中,父子组件的关系可以总结为props down,events up: 在vue2.0中废弃了 ...

随机推荐

  1. JavaScript(三)数据类型转换

    类型转换JavaScript中的取值类型非常灵活,如当JavaScript期望使用一个布尔值的时候,你可以提供其它数据类型的,JavaScript将根据需要自行转换数据类型.如下示例: 10 + “o ...

  2. 如何解决分配到Autoconfiguration IPV4 地址

    配置完服务器静态IP后,在CMD窗口中查看ip地址,发现是Autoconfiguration IPV4. 上网搜索了,是关于虚拟服务器的,但是我没有配置虚拟服务器,有点奇怪. 使用下面的教程,可以解决 ...

  3. CentOS7.2重置root密码的处理方法

    第一个里程碑 --在启动GRUB菜单中选择编辑选项,按键 "e" 进入编辑; 第二个里程碑 -- 大约在第16行找到 "ro" 将 "ro" ...

  4. VMware14虚拟机下安装Centos6.5

    一.下载VMware14,CentOS6.5光盘映像文件. https://pan.baidu.com/s/1WaTBnYuNC5dLYM_Ra2bjBQ 二.安装过程 1.打开VMware虚拟机 — ...

  5. android glide图片加载框架

    项目地址: https://github.com/bumptech/glide Glide作为安卓开发常用的图片加载库,有许多实用而且强大的功能,那么,今天就来总结一番,这次把比较常见的都写出来,但并 ...

  6. esp8266 免费wifi强推广告神器(4) 发现当前WIFI下的用户数目,IP,MAC请求http信息 在用户请求跳转后跳转

    需求: 1 获取当前连接客户端的HTTP请求各种信息 方法 get  http 请求路径  例如  /index.html   /    /pic.jpg 请求版本   HTTP/1.0     HT ...

  7. Linux内核入门到放弃-模块-《深入Linux内核架构》笔记

    使用模块 依赖关系 modutils标准工具集中的depmod工具可用于计算系统的各个模块之间的依赖关系.每次系统启动时或新模块安装后,通常都会运行该程序.找到的依赖关系保存在一个列表中.默认情况下, ...

  8. Sql Server登录失败问题

    1.启动SQL Server 2008 Management Studio,会看到 2. 里面有一个 身份验证.这个 身份验证 的下拉列表里面有两个选项: Windows 身份验证 和 SQL Ser ...

  9. JAVA关键字及作用

    ---恢复内容开始--- Java关键字及其作用 一. 总览: 访问控制 private protected public 类,方法和变量修饰符 abstract class extends fina ...

  10. python关于二分查找

    楔子 如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72 ...