一、前言

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

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. ES 6 系列 - 对于常用对象的拓展 api

    本篇中学习并记录可能会比较常用的 api ,详细请自行查找相关资料. 一.字符串的拓展 es 6 加强了对于 Unicode 的支持.javascript 允许采用 \uxxxxx 的方式表示一个字符 ...

  2. nvidia-smi实时刷新并高亮显示状态

    watch -n 1 -d nvidia-smi 间隔1秒刷新

  3. Nginx 网络事件

    L27-29 应用层(如浏览器等一系列组成的发送get请求) 传输层 系统内核打开一个端口将客户端IP及端口和服务端IP及端口记录下来一并传输到网络层 网络层 打包后到链路层 再到客户端路由器至广域网

  4. CentOS安装GIt、上传项目到git仓库

    上传项目 登录服务器后安装git yum install git 新建文件夹(仓库) mkdir *.git 初始化仓库 git init --bare *.git 在本地初始化仓库 git init ...

  5. Educational Codeforces Round 60 Div. 2

    F:考虑对于每个字母对求出删掉哪些字符集会造成字符串不合法,只要考虑相邻出现的该字母对即可,显然这可以在O(np2)(或小常数O(np3))内求出.然后再对每个字符集判断是否能通过一步删除转移而来即可 ...

  6. 第五十六 css选择器和盒模型

    1.组合选择器 群组选择器 #每个选择为可以位三种基础选择器任意一个,用逗号隔开,控制多个. div,#div,.div{ color:red } 后代(子代)选择器 .sup .sub{ 后代 } ...

  7. HUST 1541 解方程

    参考自:https://www.cnblogs.com/ECJTUACM-873284962/p/6394836.html 1541 - Student’s question 时间限制:1秒 内存限制 ...

  8. 二:C#对象、集合、DataTable与Json内容互转示例;

    导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型:    二:C#对象.集合.DataTable与Json内容互转示例: ...

  9. Paths on a Grid POJ - 1942 组合数学 (组合数的快速计算)

    题意:格路问题 没什么难度 难点在于如何快速计算相对较大的组合数 思路:运用手写计算组合数的方式进行计算  如c(8,3) 如果手算就是   8*7*6/(3*2*1)这样可以很快得解出 计算代码为: ...

  10. Matplotlib学习---用seaborn画联合分布图(joint plot)

    有时我们不仅需要查看单个变量的分布,同时也需要查看变量之间的联系,这时就需要用到联合分布图. 这里利用Jake Vanderplas所著的<Python数据科学手册>一书中的数据,学习画图 ...