原本在vue2中$attrs与$listeners双剑合璧,数据传递和事件回调用得贼舒服,但得知vue3没了$listeners,霎时间犹如小龙女误解杨过之后独自一人离开一样不知所措。还好vue3中的$attrs学会了老顽童周伯通的双手互搏的绝技那样,只有自己也可以玩。从此小龙女再也不需要杨过一起双剑合璧也能打败金轮法王了[doge]。
App.vue:
<template>
<parent to-parent="给父元素的数据" to-children="给子元素的数据" @clickEvent="clickEventCallback" />
</template>
<script setup>
import parent from 'parent.vue';
const clickEventCallback = () => {
console.log('在App.vue接收到点击的回调了');
};
</script>
parent.vue:
<template>
<div>
这里是parent:
<p>{{ props.toParent }}</p>
<children v-bind="$attrs" />
</div>
</template>
<script>
export default {
inheritAttrs: false,
};
</script>
<script setup>
import children from "./children.vue";
const props = defineProps({
toParent: String,
});
</script>
children.vue
<template>
<div @click="onClickFn">
这里是children:
<p>{{ props.toChildren }}</p>
</div>
</template>
<script setup>
const props = defineProps({
toParent: String,
toChildren: String,
});
const emit = defineEmits(["clickEvent"]);
const onClickFn = () => {
emit("clickEvent");
};
</script>
结果如下图所示:
如果在parent.vue里也在defineProps接收toChildren,那么被parent.vue截胡的children.vue里就取不到参数了。【因为$attrs传递的就是上级props不接收的参数】
同理,children.vue里的defineProps追加toParent参数也是取不到的。
当然,如果parent.vue里也想要children.vue的toChildren参数,也可以神不知鬼不觉的顺手牵羊: parent.vue:
<template>
...
<p>{{ attrs['to-children'] }}</p>
</template>
<script setup>
...
import { useAttrs } from 'vue';
const attrs = useAttrs();
</script>
结果如下图所示: