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

72 阅读1分钟

你问的是 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 }
        }
      }
      

🔑 总结对比

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