Vue3中没了$listeners之后$attrs的使用

1,977 阅读1分钟

原本在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>

结果如下图所示:

image.png

如果在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>

结果如下图所示:

image.png