Vue 项目中,组件之间的通信,用到最多的就是 父子组件、兄弟组件之间的传值,但是最近遇到一个爷孙组件,甚至更深一层的组件之间的传值,通过查资料,终于解决了。
(1)通过 $attrs 和 $listeners 来传值
下面是官网介绍:
具体的咱也没看明白,直接照着葫芦画瓢了,
首先创建一个Father 组件, 向子组件和孙组件传值,以及接收孙组件传来的方法
<template> <div class="page"> 我是爷爷辈的 <div>孙子传来的{{grandsonMsg}}</div> <children @sendGra='sendGra' :son='son' :grand='grand' :clickSend='clickSend'></children> </div> </template> <script> import children from './children' export default { name:'father', components:{ 'children':children }, data(){ return{ grandsonMsg:'', son:'给儿子的', grand:'给孙子的' } }, provide() { return { provideData: '爷爷组件第二种传值' // 祖先组件提供数据 } }, methods:{ sendGra(ele){ //孙子传来的方法 this.grandsonMsg = ele }, clickSend(){ console.log('爷爷传给孙子的方法'); } } } </script> <style> body{ padding:100px; } .page{ padding: 100px; } </style>
然后创建子组件,通过v-bind:'$attrs'来存贮父组件传给孙组件的值 和 v-on:'$listeners'来接送孙组件传给爷组件的事件
注意: 传给孙组件的数值,在子组件中不可以用props 来进行声明 需要设置 inheritAttrs: false,取消默认行为
<template> <div> <div>--------</div> 我是儿子辈的 <grandson v-on="$listeners" v-bind="$attrs"></grandson> </div> </template> <script> import grandson from './grandson' export default { components:{ grandson }, inheritAttrs: false, } </script> <style> </style>
第三步,创建孙组件接收数据和传递事件(此组件也不能用props 来接收 )传递多个时用,$attrs.name 来进行接收
<template> <div> <div>--------</div> <button @click="send">传值</button> <div>{{grand}}</div> <div>$attrs{{$attrs}}</div> <div>{{provideData}}</div> </div> </template> <script> export default { props:['grand'], data(){ return{ sendMsg:'我是你的孙子', } }, inheritAttrs: false, inject:['provideData'], methods:{ send(){ this.$emit('sendGra',this.sendMsg) } } } </script> <style> </style>
(2)通过provide 和 inject 来进行传值,提示:provide
和 inject
绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
首先: 爷组件通过 provide 进行创建值
provide() { return { provideData: '爷爷组件第二种传值' // 祖先组件提供数据 } },
最后,在孙组件中 进行 inject 接收
<template> <div> <div>{{provideData}}</div> </div> </template> <script> export default { inheritAttrs: false, inject:['provideData'], methods:{ send(){ this.$emit('sendGra',this.sendMsg) } } }
友情提示
1. provide/inject是解决组件之间的通信问题的利器,不受层级结构的限制。但也不是随便去滥用,通信代表着耦合。
2.provide/inject主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。