Vue组件之间的通讯方式数据处理:父子组件,兄弟组件,同级组件,爷孙组件

编程入门 行业动态 更新时间:2024-10-07 12:23:54

Vue<a href=https://www.elefans.com/category/jswz/34/1771375.html style=组件之间的通讯方式数据处理:父子组件,兄弟组件,同级组件,爷孙组件"/>

Vue组件之间的通讯方式数据处理:父子组件,兄弟组件,同级组件,爷孙组件

贴一张图先建立几个组件

先讲一句
每个 Vue 实例都实现了事件接口,即:
使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件Vue 的事件系统与浏览器的 EventTarget API 有所不同。尽管它们的运行起来类似,
但是 $on 和 $emit 并不是addEventListener 和 dispatchEvent 的别名,
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

那就同级兄弟之间数据的传递,刚才贴了兄弟之一,再贴一下它老弟

好了,老大想搞老二?他们之间怎么搞呢?
建个房啊,公共枢纽站多方便以后也划算
你可以随便建 我就不说了,我在src/assets/下创建一个js文件,内容如下

嗯,内容虽然少,但是我不想写啊,也防止你直接copy啊,哈哈
(eventBus中我们创建了一个新的Vue实例,以后它就承担起了组件之间通信的桥梁了,也就是中央事件总线。
(这句话不是我说的,不过的却是eventBus的确是这意思)

1、一句话就是我们在响应点击事件的sendMsg函数中,用$emit触发了一个自定义的userDefinedEvent事件,
并传递了一个字符串参数,而$emit实例方法触发当前实例(这里的当前实例就是bus)上的事件,附加参数就会传给监听器回调。

所以在 第二个组件里
在mounted中,监听了userDefinedEvent,并把传递过来的字符串参数传递给了$on监听器的回调函数
好了,三分归元气当然是把组建放到父级上去,注册这两个组件,并添加这两个组件的标签

算了,贴一下 总结

1、创建一个事件总线,例如demo中的eventBus,用它作为通信桥梁
2、在需要传值的组件中用bus.$emit触发一个自定义事件,并传递参数
3、在需要接收数据的组件中用bus.$on监听自定义事件,并在回调函数中处理传递过来的参数

好像有点长,算了,快一点,父子之间传递,父向子,子向父我这里放在了一个组件里

同时我们看到app.Vue里面的蓝2 是通过绑定的形式直接传进子组件的,不过是在子组件里的pros里面接受一下就能使用

里面的红1是子组件向父组件传值后(@reduce-parent) 是v-on 来监听子组件触发的事件,别瞎搞
至于下面methods里面写的,上面也说了,也不说了,好像完了…

对于vue来说,组件之间的消息传递是非常重要的,组件之间消息传递的各种方式有那些呢?
1. props和$emit
父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件来做到的。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src=".6.10/vue.min.js"></script>
</head>
<body>
<div id="app"><parent></parent></div>
<script>Vueponent('child', {data() {return {childMessage: this.parentMessage}},template: `<div><input type="text" v-model="childMessage" @input="passData(childMessage)"></div>`,props: ['parentMessage'],//得到父组件传递过来的数据methods: {passData(val) {this.$emit('getChildData', val)//触发父组件中的事件}}})Vueponent('parent', {template: `<div><p>this is parent compoent!{{reciveChildMemessage}}</p><child :parentMessage="parentMessage" v-on:getChildData="getChildData"></child></div>`,data() {return {parentMessage: 'hello',reciveChildMemessage: ''// 定义一个字段来接收子组件里面传来的值}},methods: {getChildData(val) {//执行子组件触发的事件this.reciveChildMemessage = val // 定义一个字段来接收子组件里面传来的值console.log(val)}}})var app = new Vue({el: '#app'})
</script>
</body>
</html>

上例中,有父组件parent和子组件child。
1).父组件传递了message数据给子组件,并且通过v-on绑定了一个getChildData事件来监听子组件的触发事件;
2).子组件通过props得到相关的message数据,最后通过this.$emit触发了getChildData事件。

2.$attrs和$listeners
第一种方式处理父子组件之间的数据传输有一个问题:如果父组件A下面有子组件B,组件B下面有组件C,这时如果组件A想传递数据给组件C怎么办呢?
Vue 2.4开始提供了$attrs$listeners来解决这个问题,能够让组件A之间传递消息给组件C。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src=".6.10/vue.min.js"></script>
</head>
<body>
<div id="app"><first></first>
</div>
<script>Vueponent('third',{template:`<div title="third, component"><input type="text" v-model="$attrs.firstToThirdMessage" @input="setThirdData($attrs.firstToThirdMessage)"></div>`,methods:{setThirdData(val){//触发父组件A中的事件this.$emit('getThirdData', val)},}})Vueponent('second',{data(){return {secondMessage:this.firstToSecondMessage}},template:`<div title="second, component"><input type="text" v-model="secondMessage" @input="setSecondData(secondMessage)"><third v-bind="$attrs" v-on="$listeners"></third></div>`,props:['firstToSecondMessage'],//得到父组件传递过来的数据methods:{setSecondData(val){//触发父组件中的事件this.$emit('getSecondData',val)}}})Vueponent('first',{template:`<div title="first, component"><p>this is first compoent!</p><p>来自Second 组件的数据:{{firstToSecondMessage}}</p><p>来自third 组件的数据:{{firstToThirdMessage}}</p><second :firstToThirdMessage="firstToThirdMessage" :firstToSecondMessage="firstToSecondMessage" v-on:getThirdData="getThirdData" v-on:getSecondData="getSecondData"></second></div>`,data(){return {firstToSecondMessage:'hello second',firstToThirdMessage:'hello third' //传递给c组件的数据}},methods:{getSecondData(val){this.firstToSecondMessage = valconsole.log('这是来自Second组件的数据:'+ val)},//执行C子组件触发的事件getThirdData(val){this.firstToThirdMessage = valconsole.log("这是来自Third组件的数据:"+val)}}})var app = new Vue({el: '#app'})
</script>
</body>
</html>

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

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src=".6.10/vue.min.js"></script>
</head>
<body>
<div id="app"><old-brother></old-brother><young-brother></young-brother>
</div>
<script>Vueponent('oldBrother',{data(){return {OldBrotherMessage:'hello youngBrother'}},template:`<div><p>this is oldBrother compoent!</p><input type="text" v-model="OldBrotherMessage" @input="passData(OldBrotherMessage)"></div>`,methods:{passData(val){bus.$emit('globalEvent',val) //触发全局事件globalEvent}}})Vueponent('youngBrother',{template:`<div style="border: 1px dotted red;"><p>this is youngBrother compoent!</p><p>oldBrother传递过来的数据:{{reciveOldBrotherMessage}}</p></div>`,data(){return {reciveOldBrotherMessage:''}},mounted(){bus.$on('globalEvent',(val)=>{//绑定全局事件globalEventthis.reciveOldBrotherMessage=val;})}})//中央事件总线var bus=new Vue();var app = new Vue({el: '#app'})
</script>
</body>
</html>

4. provide和inject
父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src=".6.10/vue.min.js"></script>
</head>
<body>
<div id="app"><parent></parent>
</div>
<script>Vueponent('child', {inject:['obj'],//得到父组件传递过来的数据data() {return {childMessage: this.obj}},template: `<div title="this is child compoent!"><input type="text" v-model="childMessage" @input="passData(childMessage)"></div>`,props: ['message'],//得到父组件传递过来的数据methods: {passData(val) {this.$emit('getChildData', val)//触发父组件中的事件}}})Vueponent('parent', {template: `<div title="this is parent compoent!"><p>this is parent compoent!{{reciveChildMemessage}}</p><child :message="message" v-on:getChildData="getChildData"></child></div>`,provide:{obj:'test'},data() {return {message: 'hello',reciveChildMemessage: ''// 定义一个字段来接收子组件里面传来的值}},methods: {getChildData(val) {//执行子组件触发的事件this.reciveChildMemessage = val// 定义一个字段来接收子组件里面传来的值}}})var app = new Vue({el: '#app'})
</script>
</body>
</html>

5. v-model
父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src=".6.10/vue.min.js"></script>
</head>
<body>
<div id="app"><parent></parent>
</div>
<script>Vueponent('child', {props: {value: String, //v-model会自动传递一个字段为value的prop属性},data() {return {childMessage: this.value}},methods: {changeValue() {this.$emit('input', this.childMessage);//通过如此调用可以改变父组件上v-model绑定的值}},template: `<div title="this is child compoent!"><input type="text" v-model="childMessage" @input="changeValue"></div>`})Vueponent('parent', {template: `<div title="this is parent compoent!"><p>this is parent compoent!</p><p>{{parentMessage}}</p><child v-model="parentMessage"></child></div>`,data() {return {parentMessage: 'hello'}}})var app = new Vue({el: '#app'})
</script>
</body>
</html>

6. $parent和$children

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src=".6.10/vue.min.js"></script>
</head>
<body>
<div id="app"><parent></parent>
</div>
<script>Vueponent('child',{props:{value:String, //v-model会自动传递一个字段为value的prop属性},data(){return {childMessage:this.value}},methods:{changeValue(){this.$parent.parentMessage = this.childMessage;//通过如此调用可以改变父组件的值}},template:`<div title="this is parent compoent!"><input type="text" v-model="childMessage" @input="changeValue"></div>`})Vueponent('parent',{template:`<div title="this is parent compoent!"><p>this is parent compoent!{{parentMessage}}</p><button @click="changeChildValue">点击将值传给子组件</button ><child></child></div>`,methods:{changeChildValue(){this.$children[0].childMessage = this.parentMessage;}},data(){return {parentMessage:'父组件的值'}}})var app = new Vue({el: '#app'})
</script>
</body>
</html>

7.boradcast和dispatch
vue1.0中提供了这种方式,但vue2.0中没有,但很多开源软件都自己封装了这种方式,比如min ui、element ui和iview等。
比如如下代码,一般都作为一个mixins去使用, broadcast是向特定的父组件,触发事件,dispatch是向特定的子组件触发事件,本质上这种方式还是on和on和emit的封装,但在一些基础组件中却很实用。

8.vuex处理组件之间的数据交互
如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。
详情可参考:/

更多推荐

Vue组件之间的通讯方式数据处理:父子组件,兄弟组件,同级组件,爷孙组件

本文发布于:2024-03-07 21:53:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1719003.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组件   数据处理   父子   兄弟   通讯

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!