Vue(基础四)_总结五种父子组件之间的通信方式
一、前言
这篇文章主要总结了几种通信方式:
1、方式一:使用props: [ ]和$emit() (适用于单层通信)
2、方式二:$attrs和$listeners(适用于多层)
二、主要内容
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(基础四)_总结五种父子组件之间的通信方式的更多相关文章
- vue之父子组件之间的通信方式
(一)props与$emit <!-这部分是一个关于父子组件之间参数传递的例子--> <!--父组件传递参数到子组件是props,子组件传递参数到父组件是用事件触发$emit--&g ...
- Vue 编程之路(一)——父子组件之间的数据传递
最近公司的一个项目中使用 Vue 2.0 + element UI 实现一个后台管理系统的前端部分,属于商城类型.其中部分页面是数据管理页,所以有很多可以复用的表格,故引入自定义组件.在这里分享一下开 ...
- C#_02.13_基础四_.NET方法
C#_02.13_基础四_.NET方法 一.方法概述: 方法是一块具有名称的代码.可以通过方法进行调用而在别的地方执行,也可以把数据传入方法并接受数据输出. 二.方法的结构: 方法头 AND 方法 ...
- 【Vue课堂】Vue.js 父子组件之间通信的十种方式
这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...
- Vue.js 父子组件之间通信的方式
Vue 父子组件之间的同学有一下几种方式: 1. props 2. $emit -- 组件封装用的比较多 3. .sync -- 语法糖 4. $attrs 和 $listeners -- 组件封装用 ...
- 【转】vue父子组件之间的通信
vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...
- vue中父子组件之间的传值、非父子组件之间的传值
在Vue实例中每个组件之间都是相互独立的,都有自己的作用域,所以组件之间是不能直接获取数据.在项目开发中一个组件可能需要获取另一个组件的值,我们可以通过其他方法间接的获取.所以,获取的方法有以下几种: ...
- 浅谈vue父子组件之间的传值
前言:本章主要说下父子组件的传值,为商品列表组件之间的传值做一个基础预热.Github:https://github.com/Ewall1106/mall(请选择分支chapter23) 1.父组件向 ...
- Vue基础-自定义事件的表单输入组件、自定义组件的 v-model
Vue 测试版本:Vue.js v2.5.13 学习 Vue 的自定义事件的表单输入组件,觉得文档讲的不太细致,所以这里再细化一下: 如果不用 v-model,代码应该是这样: <myinput ...
随机推荐
- How to remove unwant Internet Explorer Context Menu
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt
- 【SSL】OV、DV和EV证书的区别
关于https证书 https协议需要到ca申请证书,一般免费证书很少,需要交费. http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议. http和https使用 ...
- pycharm pip 源修改以及包管理(转载)
转载自(https://www.u3v3.com/ar/1352) pycharm下如何将默认的pip源改成国内能快速访问的源, 以及如何进行包管理 pycharm 是一款进行python项目开发的利 ...
- luogu P1353 【[USACO08JAN]跑步Running】
USACO!!! 唉!无一例外又是母牛(终于知道美国的牧场养什么了) 今天的主人公是一个叫贝茜的公主病母牛(好洋气) 可是她叫什么和我们理解题好像没有什么关系 通过读题我们可以发现她有三个傲娇的地方 ...
- Docker基本使用(二)
Docker 客户端 我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项. 可以通过命令 docker command --help 更深入的了解指定的 Docker 命 ...
- ☆ [POJ2559] Largest Rectangle in a Histogram 「单调栈」
类型:单调栈 传送门:>Here< 题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积 解题思路 单调栈的经典题 显然,最终的子矩形高度一定和某一个矩形相等(反证).因此一 ...
- MS-DOS 系统汇编环境之DOSBOX+vim
经过虚拟机的体验,我发现还是dosbox里汇编比较方便..... 一.下载安装 dosbox DOSBOX 准备好 masm.exe.link.exe.debug.exe,放在~/dos下(文件夹名字 ...
- Swarm stack
什么是 stack ?例如:首先创建 secret. 然后创建 MySQL service,这是 WordPress 依赖的服务. 最后创建 WordPress service. 也就是说,这个应用包 ...
- redis在centos7下安装
https://blog.csdn.net/wzygis/article/details/51705559 1.redis下载地址:http://www.redis.cn/download.html ...
- 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\),和它在同一 ...