返回

Vue 3 脚本设置:组件上使用 v-model 的终极指南

vue.js

如何在 Vue 3 脚本设置中组件上使用 v-model

问题概述

在 Vue 3 脚本设置中使用 v-model 时,你可能会遇到一个常见的警告:“组件发出‘input’事件但它未在 emits 选项或‘onInput’属性中声明”。

解决方案

为了解决这个问题,我们需要在子组件中显式声明 input 事件。使用 defineEmit 可轻松实现此目的。

子组件实现

<script setup>
import { defineProps, defineEmit } from 'vue'

const props = defineProps({
  label: String,
  value: String
})
const emit = defineEmit(['input'])

function updateValue(value) {
  emit('input', value)
}
</script>

通过 defineEmit,我们通知 Vue 子组件将发出一个名为 input 的事件。然后,在子组件中,我们使用 v-on:input="updateValue($event.target.value)" 来侦听 input 事件并更新父组件中的数据。

父组件实现

在父组件中,只需将 v-model="name" 绑定到子组件,如下所示:

// Parent.vue
<template>
  <h2>V-Model Parent</h2>
  <Child v-model="name" label="Name" />
  <p>{{ name }}</p>
</template>

总结

通过显式声明子组件中的 input 事件,我们解决了警告并实现了 v-model 的双向绑定功能。

常见问题解答

  1. 为什么需要在子组件中声明 input 事件?
    为了告知 Vue 子组件将发出 input 事件,使其能够在父组件中使用 v-model 进行数据绑定。

  2. definePropsdefineEmit 是什么?
    这是 Vue 3 中的新 API,用于在脚本设置中定义组件的属性和事件。

  3. 如何传递其他事件给父组件?
    使用 defineEmit 也可声明其他事件,并通过 @event-name 在子组件中触发。

  4. 我可以直接在子组件中使用 emit('input', value) 吗?
    可以,但建议使用 updateValue 函数来遵循 Vue 的事件处理最佳实践。

  5. 是否可以在父组件中使用 @input 来侦听子组件的 input 事件?
    是的,但这种方法不适用于 v-model,因为它仅侦听由 v-model 触发的 input 事件。