一、前言

这篇文章主要总结了几种通信方式:

1、方式一:使用props: [ ]和$emit()  (适用于单层通信)

2、方式二:$attrs和$listeners(适用于多层)

3、方式三:中央处理事件:bus.$on监听触发的事件

4、方式四:provide:[],inject:[']

5、方式五:通过给$parent  $children赋值

二、主要内容

1、方式一:使用props: [ ]和$emit()

  (1)父组件向子组件通信

  a.步骤:①先给父组件添加自定义属性

       ②子组件用props:[]接收传来的自定义属性

       ③子组件就可使用接收到的数据

  b.代码如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
*{
margin:0;
padding: 0;
} .parent{
height: 150px;
width: 400px;
background-color: blue;
} .child{
height: 100px;
width: 200px;
background-color: pink;
}
</style>
</head>
<body>
<div id='app'> </div>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript"> Vue.component('Child',{ data(){
return{ }
}, template:`<div class='child'>
这是孩子组件
<input :value='childData'/> </div>`, props:['childData'] }) var Parent = {
data(){
return{
msg:'这是父组件的数据'
}
}, template:`<div class='parent'>
这是父组件:
<Child :childData='msg'></Child>
</div>
`
} new Vue({
el:"#app",
data(){
return{ }
}, template:`<Parent></Parent>`,
components:{
Parent
}
})
</script>
</body>
</html>

父组件向子组件传递数据.html

   c.测试结果:孩子组件接收到了父组件的数据,并且显示在孩子组件的input框里

  d.具体实现:

  (2)子组件向父组件通信

  步骤:①现在父组件中定义自定义事件

     ②子组件中定义一个原生的事件,调用下面methods中定义的

     ③在子组件的method()中定义一个事件,用$emit(),来触发父组件的事件,

  代码如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
*{
margin:0;
padding: 0;
} .parent{
height: 150px;
width: 400px;
background-color: blue;
} .child{
height: 100px;
width: 200px;
background-color: pink;
}
</style>
</head>
<body>
<div id='app'> </div>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript"> Vue.component('Child', {
data(){
return{
childData:'孩子'
}
},
template:`<div class='child'>
这是孩子组件
<input v-model='childData' @input='childerValue(childData)'/> </div>`, methods:{
childerValue:function(val){
this.$emit('childerHander', val)
} } }) var Parent = {
data(){
return {
msg:'' }
}, template:`<div class='parent'> <Child @childerHander='childerHander'></Child>
</div>`, methods:{ childerHander:function(val){
console.log(val) }
}
} new Vue({
el:'#app',
data(){
return{ }
},
template:`<div>
<Parent></Parent> </div>`, components:{
Parent
} })
</script> </body>
</html>

孩子的数据传到父组件中.html

  测试

  具体实现:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

方式二:$attrs和$listeners

第一种方式适合用于单层嵌套的情况,如果组件中有三层嵌套如果用第一种那么需要在每个子组件中定义props:[]接收,这样实现起来比较麻烦,在vue2.4开始提供了$attrs和$listeners来解决这个问题

能够让组件A之间传递消息给组件C

如下所示:

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.a{
width: 400px;
height: 400px;
background-color: blue; } .b{
width: 300px;
height: 300px;
background-color: orange; } .c{
width: 200px;
height: 200px;
background-color: pink; }
</style>
</head>
<body>
<div id='app'>
</div>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript">
//定义组件cc Vue.component('C',{
data(){
return{ }
},
template:`<div class='c'>
这是c组件
<div>{{$attrs.messagec}}</div> </div>`
}) Vue.component('B',{
data(){
return{ }
},
template:`<div class='b'>
<C v-bind='$attrs'></C> </div>`
}) //定义组件A
Vue.component('A', {
data(){
return{ }
}, //1.先接收
props:['message'], template:`<div class='a'>
<B v-bind='$attrs'></B> </div>`
}); //定义组件App----A
var App = {
data(){
return{
msg:'我是父组件的内容',
messagec:'helloc'
}
}, template:`<div>
这是一个父组件
<A :messagec='messagec'></A> </div>`
} new Vue({
el:'#app',
data(){
return{ }
}, components:{
App
}, template:'<App />' })
</script>
</body>
</html>

方式二父组件向子组件通信.html

测试:

具体实现:

  (2)子组件向父组件传递信息

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.a{
width: 400px;
height: 400px;
background-color: blue; } .b{
width: 300px;
height: 300px;
background-color: orange; } .c{
width: 200px;
height: 200px;
background-color: pink; }
</style>
</head>
<body>
<div id='app'>
</div>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript">
//定义组件cc Vue.component('C',{
data(){
return{ }
},
template:`<div class='c'>
这是c组件
<input @input='cClickHandler' /> </div>`,
methods:{
cClickHandler(){
alert(1)
this.$emit('getCData','这是c的数据')
}
}
}) Vue.component('B',{
data(){
return{ }
},
template:`<div class='b'>
<C v-on='$listeners'></C> </div>`
}) //定义组件A
Vue.component('A', {
data(){
return{ }
},
//1.先接收
props:['message'], template:`<div class='a'>
<B v-on='$listeners'></B> </div>`
}); //定义组件App----A
var App = {
data(){
return{
msg:'我是父组件的内容',
messagec:'helloc'
}
},
template:`<div>
这是一个父组件
<A v-on:getCData='getCData'></A>
</div>`,
methods:{
getCData(val){
console.log(val)
}
}
} new Vue({
el:'#app',
data(){
return{ }
}, components:{
App
}, template:'<App />' })
</script>
</body>
</html>

方式二父组件向子组件传递数据.html

  测试如下:

  具体实现:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

方式三:上面两种方式都是父子组件之间数据的传递,如果两个组件不是父子关系呢?这种情况下可以使用中央事件总线的方式,新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件

例子如下:

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.brotherB{
width: 400px;
height: 400px;
background-color: blue;
} .brotherC{
width: 200px;
height: 200px;
background-color: pink;
}
</style>
</head>
<body> <div id='app'> </div>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
//中央事件总线
var bus = new Vue();
//B->C传事件
Vue.component('brotherC', {
data(){
return{
msg:'hello brotherB'
}
}, template:`<div class="brotherC">
我是老大(brotherC)
<input type='text' v-model='msg' @input='passData(msg)'/> </div>`,
methods:{
passData(val) { bus.$emit('globalEvent',val) //去触发
}
}
}); Vue.component('brotherB', {
data(){
return{ brother2Msg:''
}
}, template:`<div class="brotherB">
<p>我是老二(brotherB)</p>
<p>老大传递过来的数据:{{brother2Msg}}</p> </div>`,
//首先给brotherB绑定一个全局的事件
mounted(){ bus.$on('globalEvent', (val)=>{ this.brother2Msg = val;//这里用箭头函数,避免避免this改变 })
} }); var App = {
data(){
return{
msg:'我是父组件的内容'
}
}, template:`<div> <brotherC></brotherC>
<brotherB></brotherB> </div>`
} new Vue({
el:"#app",
data(){
return{ }
}, template:'<App/>',
components:{
App
} }) </script> </body>
</html>

方式三:兄弟之间通信.html

演示效果如下:

具体实现:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

方式四:父组件中通过provide来提供变量,然后在子组件中通过inject来注入变量,不论子组件有多深,只要调用了inject那么就可以注入provider中自定义的属性,而不只仅仅是从prop中接受到的数据,只要在生命周期内,子组件都可以调用

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='app'> </div>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('Child', { data(){
return {
msg:''
}
}, template:`<div>
我是孩子{{msg}} </div>`,
//2.注入
inject:['for'], created(){
//3.拿到
this.msg = this.for
}
}) Vue.component('Parent', {
template:`<div>
<p>我是父</p>
<Child /> </div>`
})
var App = {
data(){
return{ }
},
//1。提供
provide:{
for:'[这是父组件的信息]'
}, template:`<div>
<h2>我是入口组件</h2>
<Parent /> </div>`
} new Vue({
el:"#app",
data(){
return { }
}, template:'<App/>',
components:{
App
} })
</script>
</body>
</html>

方式四父组件向子组件通信.html

测试如下:

 

------------------------------------------------------------------------------------------------------------------------------------------------------------

方式五:$parent $children

代码实现:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.child{
width: 300px;
height: 300px;
background-color: pink;
} .parent{
width: 500px;
height: 500px;
background-color: blue;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('Child',{
data(){
return{
mymessage:''
}
},
template:`<div class="child">
<input type="text" v-model="mymessage" @input='changeValue'/> </div>`,
methods:{
changeValue(){
this.$parent.message = this.mymessage
}
}
}) Vue.component("Parent",{
data(){
return{
message:"hello"
}
},
template:`<div class="parent">
<p>我是父组件{{message}}</p> <Child></Child> </div>`, methods:{ }
}) var App={
data(){
return{ }
},
template:`<div>
<h2>我是入口组件</h2>
<Parent />
</div>`
} new Vue({
el:"#app",
data(){
return{ }
}, template:`<App />`,
components:{
App
}
})
</script>
</body>
</html>

子向父传

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
*{
margin:0;
padding: 0;
} .parent{
height: 150px;
width: 400px;
background-color: blue;
} .child{
height: 100px;
width: 200px;
background-color: pink;
} </style> </head>
<body>
<div id='app'> </div>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript"> Vue.component('Child', {
props:{//子组件通过props接收父组件的value props:[]也可以
value:String,
}, data(){
return{
mymessage:this.value //将上面的this.value赋值给mymessage }
}, template:`<div class='child'>
<input type="text" v-model='mymessage' @input='changeValue' /> </div>`, methods:{
changeValue(){//通过$parent将子组件的信息传递给孩子 this.$parent.message = this.mymessage;
console.log(this.$parent)
}
} }) Vue.component('Parent',{
//当点击之后,
template:`<div class='parent'>
<p>我是父亲组件{{message}}</p>
<button @click='changeValue'>test</button>
<Child></Child> </div>`,
methods:{//通过$chidren[0]传递给孩子
changeValue(){
this.$children[0].mymessage = 'hello'
}
},
data(){
return {
message:'hello'
}
}
}) var App = {
data(){
return{ }
},
template:`<div>
<h2>我是入口组件</h2>
<Parent/> </div>`
} new Vue({
el:"#app",
data(){
return{ }
}, template:'<App/>',
components:{
App
} })
</script> </body>
</html>

方式五组件通信.html

测试:

三、总结

1、常用的方式是前三种

Vue(基础四)_总结五种父子组件之间的通信方式的更多相关文章

  1. vue之父子组件之间的通信方式

    (一)props与$emit <!-这部分是一个关于父子组件之间参数传递的例子--> <!--父组件传递参数到子组件是props,子组件传递参数到父组件是用事件触发$emit--&g ...

  2. Vue 编程之路(一)——父子组件之间的数据传递

    最近公司的一个项目中使用 Vue 2.0 + element UI 实现一个后台管理系统的前端部分,属于商城类型.其中部分页面是数据管理页,所以有很多可以复用的表格,故引入自定义组件.在这里分享一下开 ...

  3. C#_02.13_基础四_.NET方法

    C#_02.13_基础四_.NET方法 一.方法概述: 方法是一块具有名称的代码.可以通过方法进行调用而在别的地方执行,也可以把数据传入方法并接受数据输出. 二.方法的结构: 方法头  AND  方法 ...

  4. 【Vue课堂】Vue.js 父子组件之间通信的十种方式

    这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...

  5. Vue.js 父子组件之间通信的方式

    Vue 父子组件之间的同学有一下几种方式: 1. props 2. $emit -- 组件封装用的比较多 3. .sync -- 语法糖 4. $attrs 和 $listeners -- 组件封装用 ...

  6. 【转】vue父子组件之间的通信

    vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...

  7. vue中父子组件之间的传值、非父子组件之间的传值

    在Vue实例中每个组件之间都是相互独立的,都有自己的作用域,所以组件之间是不能直接获取数据.在项目开发中一个组件可能需要获取另一个组件的值,我们可以通过其他方法间接的获取.所以,获取的方法有以下几种: ...

  8. 浅谈vue父子组件之间的传值

    前言:本章主要说下父子组件的传值,为商品列表组件之间的传值做一个基础预热.Github:https://github.com/Ewall1106/mall(请选择分支chapter23) 1.父组件向 ...

  9. Vue基础-自定义事件的表单输入组件、自定义组件的 v-model

    Vue 测试版本:Vue.js v2.5.13 学习 Vue 的自定义事件的表单输入组件,觉得文档讲的不太细致,所以这里再细化一下: 如果不用 v-model,代码应该是这样: <myinput ...

随机推荐

  1. How to remove unwant Internet Explorer Context Menu

    HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt

  2. 【SSL】OV、DV和EV证书的区别

    关于https证书 https协议需要到ca申请证书,一般免费证书很少,需要交费. http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议. http和https使用 ...

  3. pycharm pip 源修改以及包管理(转载)

    转载自(https://www.u3v3.com/ar/1352) pycharm下如何将默认的pip源改成国内能快速访问的源, 以及如何进行包管理 pycharm 是一款进行python项目开发的利 ...

  4. luogu P1353 【[USACO08JAN]跑步Running】

    USACO!!! 唉!无一例外又是母牛(终于知道美国的牧场养什么了) 今天的主人公是一个叫贝茜的公主病母牛(好洋气) 可是她叫什么和我们理解题好像没有什么关系 通过读题我们可以发现她有三个傲娇的地方 ...

  5. Docker基本使用(二)

    Docker 客户端 我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项. 可以通过命令 docker command --help 更深入的了解指定的 Docker 命 ...

  6. ☆ [POJ2559] Largest Rectangle in a Histogram 「单调栈」

    类型:单调栈 传送门:>Here< 题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积 解题思路 单调栈的经典题 显然,最终的子矩形高度一定和某一个矩形相等(反证).因此一 ...

  7. MS-DOS 系统汇编环境之DOSBOX+vim

    经过虚拟机的体验,我发现还是dosbox里汇编比较方便..... 一.下载安装 dosbox DOSBOX 准备好 masm.exe.link.exe.debug.exe,放在~/dos下(文件夹名字 ...

  8. Swarm stack

    什么是 stack ?例如:首先创建 secret. 然后创建 MySQL service,这是 WordPress 依赖的服务. 最后创建 WordPress service. 也就是说,这个应用包 ...

  9. redis在centos7下安装

    https://blog.csdn.net/wzygis/article/details/51705559 1.redis下载地址:http://www.redis.cn/download.html ...

  10. BZOJ2801/洛谷P3544 [POI2012]BEZ-Minimalist Security(题目性质发掘+图的遍历+解不等式组)

    题面戳这 化下题面给的式子: \(z_u+z_v=p_u+p_v-b_{u,v}\) 发现\(p_u+p_v-b_{u,v}\)是确定的,所以只要确定了一个点\(i\)的权值\(x_i\),和它在同一 ...