$attrs 用于父组件隔代向孙组件传值
$ listeners用于孙组件隔代向父组件传值
这两个也可以同时使用,达到父组件和孙组件双向传值的目的。
A组件(App.vue)
<template>
<div id="app">
<!-- 此处监听了两个事件,可以在B组件或者C组件中直接触发 -->
<child1 :pchild1="child1" :pchild2="child2" :pchild3="child3" @method1="onMethod1" @method2="onMethod2"></child1>
</div>
</template>
<script>
import Child1 from "./Child1.vue";
export default {
data() {
return {
child1: '1',
child2: 2,
child3: {
name: 'child3'
}
};
},
components: { Child1 },
methods: {
onMethod1(msg1) {
console.log(`${msg1} running`);
},
onMethod2(msg2) {
console.log(`${msg2} running`);
},
},
};
</script>
B组件(Child1.vue)
<template>
<div class="child-1">
<h2>in child1</h2>
<p>props: {{ pchild1 }}</p>
<p>$attrs: {{ $attrs }}</p>
<hr/>
<!-- 通过 v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
<!-- C组件中能直接触发test的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
<child2 v-bind="$attrs" v-on="$listeners"></child2>
</div>
</template>
<script>
import Child2 from "./Child2.vue";
export default {
data() {
return {
child1:'child1'
};
},
components: { Child2 },
props: {
pchild1:{
type:String
}
},
inheritAttrs: false,
mounted() {
this.$emit("method1",this.child1);
},
};
</script>
C 组件 (Child2.vue)
<template>
<div class="child-2">
<h2>in child2:</h2>
<p>props: {{ pChild2 }}</p>
<p>$attrs: {{ $attrs }}</p>
<p>pchild3Name: {{ $attrs.pchild3.name }}</p>
<hr />
</div>
</template>
<script>
export default {
data() {
return {
child2: 'child2'
};
},
props: {
pChild2: {
type: String,
}
},
inheritAttrs: false,
mounted() {
this.$emit("method2", this.child2);
},
};
</script>