Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

在 vue 的自定义组件中实现 v-model

vue2 自定义组件的 v-model

<input v-model="val">
<!-- 等价于 -->
<input :value="val" @input="val = $event.target.value">

...
return{
val:''
}
...
<!-- 自定义组件 -->
<template>
  <input :value="value" @input="updateSomething">
<template/>
props:{
  // vue2 默认会使用 value这个变量名
  value:String
},
mathod:{
  updateSomething(e){
    // vue2 默认使用 input 事件
    this.$emit("input",e.target.checked)
  }
}
...

vue2 自定义属性名或者事件

<!-- 通过自定义事件更新 -->
<ChildComponent v-model="checked" />

...
return {
    checked:false
}
...
<template>
  <input type="checkbox" :title="checked" @change="updateSomething">
<template/>

// 子组件定义
export default {
    // 自定义事件名或属性名要在model中定义
  model: {
    prop: checked,
    event: change
  }
  props: {
    checked: {
      checked:Boolean
    },
    methods:{
       // 通过发布自定义事件更新
       updateSomething(e){
         this.$emit("change",e.target.checked)
       }
    }
  }
}

缺点

  1. 无论是原生组件还是自定义组件都只能存在一个 v-model
  2. 繁琐

vue3 自定义组件的 v-model

Vue3 中则不在使用 model 选项而是通过 props 参数来实现 v-model

<ChildComponent v-model="pageTitle" />
<!-- 相当于 -->
<ChildComponent
  :modelValue="pageTitle"
  @update:modelValue="pageTitle = $event"
/>
// ChildComponent.vue

export default defineComponent({
  props: {
    modelValue: String // 以前在model属性中是`value:String`
  },
  setup(props,context){
    const changePageTitle = (e: KeyboardEvent) => {
      const targetValue = (e.target as HTMLInputElement).value
      inputRef.val = targetValue
      context.emit('update:modelValue', title)  // 以前是 `this.$emit('input', title)`
      }
    }
})

vue3 的 v-model 中定义多个属性

<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />

<!-- 是以下的简写: -->

<ChildComponent
  :title="pageTitle"
  @update:title="pageTitle = $event"
  :content="pageContent"
  @update:content="pageContent = $event"
/>

v-model | Vue.js (vuejs.org)