为什么 @change 或 @input 可以与自定义 v-model 组件一起使用?

dan*_*ner 2 javascript vue.js v-model vuejs3

假设我创建了一个自定义组件Comp.vue,它基本上是一个带有model-valueprop 和 的包装输入元素@update="$emit('update:modelValue', $event.target.value)

它可能看起来像这样:

<template>
  <div>
  <label :for="name" class="block relative">
    <div>
        {{ label }}
    </div>
        <input
          :name="name"
          :type="type"
          :value="modelValue"
          @input="$emit('update:modelValue', $event.target.value)"
        />
  </label>
    </div>
</template>

<script>

export default {
  props: {
    label: {
      required: true,
      type: String,
    },
    modelValue: {
      required: false,
      default: "",
      type: [String, Number],
    },
    type: {
      default: "text",
      type: String,
    },
    name: {
      required: false,
      type: String,
      default: "",
    },
  },
  emits: ["update:modelValue"],
};
</script>
Run Code Online (Sandbox Code Playgroud)

现在我已将该组件导入到 App.vue 中。

为什么这有效:

<Comp @change="doSth1()" />
<Comp @input="doSth2()" />
Run Code Online (Sandbox Code Playgroud)

我的自定义Comp.vue从不发出任何这些事件。

我创建了一个记录这些事件的自定义游乐场: Playground Link

Tol*_*ela 5

由于inputchange是原生 DOM 事件,Vue 会自动监听它们。

请检查 Vue 文档:指令、v-onHTMLElement、输入事件

当在普通元素上使用时,它仅侦听本机 DOM 事件。当在自定义元素组件上使用时,它会侦听该子组件上发出的自定义事件。

看起来 Vue 仍然通过自定义组件监听原生 HTML 输入事件。

例如,还有一个beforeinput事件也是由 Vue 自动触发并监听的。因此您也可以为其添加指令。

@beforeinput="beforeinputTriggered()"
Run Code Online (Sandbox Code Playgroud)

更新以回答@Thibault

modelValue 本身的更改不会触发“输入/更改”事件。如果我们删除 Comp.vue 中的 HTML 输入元素,那么“beforeinput/input/change”事件将不会被触发。

证据如下:具有 +1 按钮的同一组件仅触发该@update:modelValue事件。

在此输入图像描述