0
点赞
收藏
分享

微信扫一扫

vue子组件获取父组件在其上绑定的事件

在 Vue 中,子组件获取父组件在其上绑定的事件,通常有两种场景:透传事件到子组件内部元素在子组件逻辑中手动触发父组件事件。:

Vue 2 中的实现

1. 透传事件到子组件内部元素

使用 $listeners 将父组件绑定的事件传递给子组件内部元素:

<!-- 父组件 Parent.vue -->
<template>
  <Child @click="handleClick" @custom-event="handleCustom" />
</template>

<script>
export default {
  methods: {
    handleClick() { console.log('父组件的点击事件'); },
    handleCustom() { console.log('父组件的自定义事件'); }
  }
}
</script>

<!-- 子组件 Child.vue -->
<template>
  <!-- 将父组件的事件绑定到内部按钮 -->
  <button v-on="$listeners">点击触发所有事件</button>
</template>

2. 在子组件逻辑中手动触发事件

通过 this.$emit(eventName) 触发父组件事件:

<!-- 子组件 Child.vue -->
<template>
  <button @click="triggerEvents">点击手动触发事件</button>
</template>

<script>
export default {
  methods: {
    triggerEvents() {
      this.$emit('click');        // 触发父组件的 @click
      this.$emit('custom-event'); // 触发父组件的 @custom-event
    }
  }
}
</script>

Vue 3 中的实现

1. 透传事件到子组件内部元素

使用 v-bind="$attrs"(Vue 3 中事件和属性合并到 $attrs):

<!-- 父组件 Parent.vue -->
<template>
  <Child @click="handleClick" @custom-event="handleCustom" />
</template>

<script setup>
const handleClick = () => console.log('父组件的点击事件');
const handleCustom = () => console.log('父组件的自定义事件');
</script>

<!-- 子组件 Child.vue -->
<template>
  <!-- 将父组件的事件绑定到内部按钮 -->
  <button v-bind="$attrs">点击触发所有事件</button>
</template>

2. 在子组件逻辑中手动触发事件

通过 emit 函数触发事件(需声明 emits):

<!-- 子组件 Child.vue -->
<template>
  <button @click="triggerEvents">点击手动触发事件</button>
</template>

<script setup>
import { defineEmits } from 'vue';

// 声明组件支持的事件
const emit = defineEmits(['click', 'custom-event']);

const triggerEvents = () => {
  emit('click');        // 触发父组件的 @click
  emit('custom-event'); // 触发父组件的 @custom-event
};
</script>

关键区别

功能 Vue 2 Vue 3
事件对象 $listeners 合并到 $attrs
事件声明 无显式声明 需通过 defineEmits 声明
触发事件方法 this.$emit(eventName) emit(eventName)
透传事件 v-on="$listeners" v-bind="$attrs"

场景示例

场景 1:透传原生事件

父组件绑定 @click(原生事件),子组件内部元素响应点击:

<!-- 父组件 -->
<Child @click="handleClick" />

<!-- 子组件 Child.vue (Vue 3) -->
<template>
  <!-- 将点击事件绑定到内部 div -->
  <div class="wrapper" v-bind="$attrs">
    <p>点击此区域触发父组件的点击事件</p>
  </div>
</template>

场景 2:手动触发多个事件

子组件在异步操作完成后触发父组件事件:

<!-- 子组件 Child.vue (Vue 3) -->
<script setup>
import { defineEmits } from 'vue';

const emit = defineEmits(['success', 'error']);

const fetchData = async () => {
  try {
    await api.getData();
    emit('success'); // 触发父组件的 @success
  } catch (err) {
    emit('error', err); // 触发父组件的 @error 并传递错误对象
  }
};
</script>

总结

  • 透传事件:直接将父组件的事件绑定到子组件内部元素(通过 $listeners$attrs)。
  • 手动触发:在子组件逻辑中通过 $emit/emit 方法触发事件。
  • Vue 3 注意:使用 defineEmits 声明事件,提高代码可读性和类型安全。
举报

相关推荐

0 条评论