一、$attrs和$listeners实现爷孙组件通信(透传)
1、在爷孙组件传参时,父组件往往是不需要知道都传递了哪些参数,也不需要使用,仅仅只是作为爷孙沟通的桥梁。$attrs就可以收集上一层组件所传递的所有props,$listeners可以收集到所有需要传递的事件。
$attrs包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 props 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件——在创建更高层次的组件时非常有用。
$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用。
如果你不希望组件的根元素继承 attribute,你可以在组件的选项中设置
inheritAttrs: false
。
2、代码示例
爷组件
<template>
<div id="app">
<children
:msg="msg"
:title="title"
@test1="onTest1"
@test2="onTest2">
</children>
</div>
</template>
<script>
import children from './children.vue';
export default {
data () {
return {
msg:"来自爷组件的消息",
title:"来自爷组件的title"
};
},
components: { children },
methods: {
oneEvent () {
console.log('oneEvent ');
},
twoEvent () {
console.log('twoEvent ');
}
}
};
</script>
父组件
<template>
<div>
<p>props: {{title}} + {{msg}}</p>
<p>$attrs: {{$attrs}}</p>
<grandson v-bind="$attrs" v-on="$listeners"></grandson>
</div>
</template>
<script>
import grandson from './grandson.vue';
export default {
props: ['title','msg'],
data () {
return {};
},
inheritAttrs: false,
components: { grandson },
mounted () {
this.$emit('twoEvent');
}
};
</script>
孙组件
<template>
<div>
<p>props: {{title}} + {{msg}}</p>
<p>$attrs: {{$attrs}}</p>
<button @click="onClick">按钮</button>
</div>
</template>
<script>
export default {
props: ['title','msg'],
data () {
return {};
},
inheritAttrs: false,
methods:{
onClick(){
this.$emit("twoEvent")
},
},
mounted () {
this.$emit('oneEvent');
},
};
</script>
注意:
如果在下级组件中不设置inheritAttrs: false
,将会带来副作用:上级标签会将传递的prop当做普通的元素特性添加在标签上,这是我们不希望看到的。
二、provide和inject
通过provide/inject可以轻松实现跨级访问祖先组件的数据,provide/inject总是成对出现的;
父组件
<script>
import children from './children.vue';
export default {
components: {
children
},
provide() {
return {
title: {
color: 'red',
fontSize:"12px",
text:"祖先级数据"
}
};
},
mounted() {
console.log(this.title); // undefined
}
};
</script>
在任意子孙辈组件中都可以通过inject注入祖先级provide提供的数据:
<script>
export default {
inject: ['title'],
mounted() {
console.log(this.title);
}
};
</script>
版权声明:本文为m0_47135993原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。