Vue2中的$listeners 和Vue3中的$attrs用法

252 阅读1分钟

Vue2中的$listeners

用于底层组件向高级层组件传递信息。

例如有 父组件A,子组件B,孙组件C 三个组件,如果C传递信息给B则可直接使用$emit,如果是C向A传递信息还使用$emit,则就需要C先$emit给B,B再$emit给A,这种方式比较繁琐,则此时可以使用v-on="$listeners"来满足当前需求。

用例:

C组件

<template>
  <div @click="onClick">C组件</div>
</template>
 
onClick(){
  this.$emit("Msg",'123')
}

B组件

<template>
  <cCom v-on="$listeners"/>
</template>

A组件

<template>
  <bCom @Msg='Msg'/>
</template>
 
methods:{
  Msg(val){
    console.log(val) //123
  }
}

Vue3中的$attrs

如下 父组件App,子组件parent,孙组件children 三个组件

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