返回

Vue 3 的组件状态变更后正确使用 emit

前端

当 Vue 3 组件的状态发生变化时,你希望在恰当的时机触发 emit 事件。这对于确保组件之间的通信流畅至关重要。本文将探讨在组件状态变更后使用 emit 的正确方法,提供清晰的示例和最佳实践。

在探索最佳实践之前,我们先用一个简短的示例来说明问题背景:

问题背景:

我们有一个父组件 Parent,它包含一个子组件 RevertButton。RevertButton 组件接受一个名为 isDeleted 的属性,用于控制其外观(已删除或正常)。以下是示例伪代码:

// Parent.vue
<template>
  <RevertButton :isDeleted="isDeleted" @revert="onRevert" />
</template>

<script>
import RevertButton from './RevertButton.vue'
export default {
  components: { RevertButton },
  data() { return { isDeleted: false } },
  methods: { onRevert() { /* 处理回滚逻辑 */ } }
}
</script>
// RevertButton.vue
<template>
  <div :class="{ 'is-deleted': isDeleted }">
    <button @click="$emit('revert')">Revert</button>
  </div>
</template>

<script>
export default {
  props: { isDeleted: { type: Boolean, default: false } },
  emits: ['revert']
}
</script>

在这种情况下,我们希望在用户单击子组件中的按钮时触发 revert 事件。但这可能会带来问题,具体取决于 emit 的时机。

最佳实践:

为了在组件状态变更后正确使用 emit,请遵循以下最佳实践:

1. 使用 Watcher:

使用 Vue 的 watch 选项来监听组件状态的变化。当状态发生变化时,触发 emit 事件。例如:

export default {
  // ... 其他代码
  watch: {
    isDeleted(val, oldVal) {
      if (val !== oldVal) {
        this.$emit('revert')
      }
    }
  }
}

2. 使用 Computed 属性:

在一些情况下,你可以使用计算属性来跟踪组件状态的变化,然后在 computed 属性值发生变化时触发 emit 事件。例如:

export default {
  // ... 其他代码
  computed: {
    isButtonVisible() {
      return !this.isDeleted
    }
  },
  watch: {
    isButtonVisible(val, oldVal) {
      if (val !== oldVal) {
        this.$emit('revert')
      }
    }
  }
}

3. 避免在模板中直接 emit

在模板中直接使用 v-on 指令触发 emit 事件的做法是不推荐的。这可能会导致性能问题和代码可维护性差。

4. 使用自定义事件:

为了提高代码的可重用性和可维护性,建议使用自定义事件而不是通用事件(如 inputclick)。这允许你更明确地指定事件的用途。