Vue 2 中的 v-model和Vue3中的v-model

你问的是 v-model (不是 v-modal 吧 😄),我来帮你梳理一下 Vue2 和 Vue3 的 v-model 区别


🔹 Vue 2 中的 v-model

  1. 语法

    复制代码
    <input v-model="msg">
    • v-model 本质上是 语法糖,等价于:

      复制代码
      <input
        :value="msg"
        @input="msg = $event.target.value"
      >
  2. 在组件中的用法

    • 默认情况下,v-model 会绑定到 value prop ,并监听 input 事件

      复制代码
      <!-- 父组件 -->
      <my-input v-model="msg"></my-input>
      
      <!-- 子组件 -->
      <template>
        <input :value="value" @input="$emit('input', $event.target.value)">
      </template>
      <script>
      export default {
        props: ['value']
      }
      </script>
    • 如果想改 prop 名和事件名,需要用 model 选项

      复制代码
      export default {
        model: {
          prop: 'checked',
          event: 'change'
        },
        props: ['checked']
      }

      父组件就可以写:

      复制代码
      <my-checkbox v-model="isChecked" />

🔹 Vue 3 中的 v-model

  1. 语法

    • 仍然是语法糖,但和 Vue2 不同:

      复制代码
      <input v-model="msg">

      等价于:

      复制代码
      <input
        :modelValue="msg"
        @update:modelValue="msg = $event"
      >
  2. 在组件中的用法

    • 默认 prop 变成了 modelValue ,事件名变成了 update:modelValue

      复制代码
      <!-- 父组件 -->
      <my-input v-model="msg"></my-input>
      
      <!-- 子组件 -->
      <template>
        <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
      </template>
      <script>
      export default {
        props: ['modelValue']
      }
      </script>
  3. v-model 支持

    • Vue3 可以在一个组件上用多个 v-model,通过参数区分:

      复制代码
      <user-name v-model:first-name="first" v-model:last-name="last" />

      子组件写法:

      复制代码
      export default {
        props: ['firstName', 'lastName'],
        emits: ['update:firstName', 'update:lastName']
      }
  4. 修饰符传递

    • Vue2 的修饰符(如 .trim.lazy)只能在内置组件里生效;

    • Vue3 可以让自定义组件接收修饰符:

      复制代码
      <my-input v-model.trim="msg" />

      子组件里通过第二个参数获取:

      复制代码
      export default {
        props: ['modelValue'],
        emits: ['update:modelValue'],
        setup(props, { emit, attrs }) {
          console.log(attrs['v-model-modifiers']); // { trim: true }
        }
      }

🔑 总结对比

特性 Vue2 Vue3
默认 prop value modelValue
默认事件 input update:modelValue
自定义 prop+事件 model: { prop, event } 直接用 v-model:xxx
多个 v-model ❌ 不支持 ✅ 支持
修饰符传递 ❌ 不支持(仅限原生表单) ✅ 支持传递到子组件