You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3组合式API如何自定义v-model绑定的prop?

Vue3组合式API中自定义v-model的prop方法

在Vue2中,v-model默认绑定value prop,但也可以自定义其他prop,示例代码如下:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

我希望在Vue3组合式API中实现同样的功能,请问如何在Vue3组合式API中为v-model定义自定义prop?
我尝试了如下示例代码,但defineModel并不存在,不过思路应该接近正确:

<script setup lang="ts">

defineProps({
    msg: {
        type: String,
    }
});

defineEmits(['update:msg'])

defineModel('msg', 'update:msg'); 

</script>

<template>
    <div>
        {{ msg }}
    </div>
    <button @click="$emit('update:msg', 'Clicked!')">Switch</button>
</template>

方案一:手动绑定Prop和Emit(兼容所有Vue3版本)

Vue3移除了Vue2的model选项,改用**v-model:自定义prop名**的语法实现自定义绑定。组件内部只需三步:

  1. 定义接收的目标prop
  2. 定义对应格式的更新事件(固定为update:自定义prop名)
  3. 触发更新时通过$emit派发事件

修正你的示例代码如下:

<script setup lang="ts">
// 定义接收的prop
const props = defineProps({
  msg: {
    type: String,
    required: true
  }
});

// 定义更新事件
const emit = defineEmits(['update:msg']);
</script>

<template>
  <div>{{ msg }}</div>
  <!-- 点击时派发更新事件并传递新值 -->
  <button @click="emit('update:msg', 'Clicked!')">Switch</button>
</template>

父组件使用时,通过v-model:msg绑定数据:

<ChildComponent v-model:msg="parentMsg" />

如果要实现默认v-model绑定自定义prop(父组件无需写:msg,直接用v-model),只需将prop命名为modelValue,事件命名为update:modelValue:

<script setup lang="ts">
const props = defineProps({
  modelValue: { // 对应默认v-model的prop
    type: String,
    required: true
  }
});

const emit = defineEmits(['update:modelValue']);
</script>

<template>
  <div>{{ modelValue }}</div>
  <button @click="emit('update:modelValue', 'Clicked!')">Switch</button>
</template>

父组件直接使用:

<ChildComponent v-model="parentMsg" />

方案二:使用Vue3.4+的defineModel语法糖(简化写法)

你尝试的defineModel是Vue3.4版本才稳定的语法糖,低版本需要开启实验性支持。它可以省去手动定义prop和emit的步骤,直接创建双向绑定的引用:

自定义prop名的写法

<script setup lang="ts">
// 指定自定义prop为msg,对应的更新事件自动为update:msg
const msgModel = defineModel({
  prop: 'msg',
  type: String,
  required: true
});
</script>

<template>
  <div>{{ msgModel.value }}</div>
  <!-- 直接修改value即可触发更新,无需手动emit -->
  <button @click="msgModel.value = 'Clicked!'">Switch</button>
</template>

父组件依然用v-model:msg="parentMsg"绑定。

默认v-model的写法(无需指定prop名)

<script setup lang="ts">
// 默认绑定modelValue和update:modelValue
const model = defineModel({
  type: String,
  required: true
});
</script>

<template>
  <div>{{ model.value }}</div>
  <button @click="model.value = 'Clicked!'">Switch</button>
</template>

父组件直接使用:

<ChildComponent v-model="parentMsg" />

低版本兼容配置

如果你的Vue版本低于3.4,需要在构建配置中开启defineModel实验性支持:

// vite.config.js
export default {
  plugins: [
    vue({
      script: {
        defineModel: true
      }
    })
  ]
}

内容的提问来源于stack exchange,提问作者vernou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:20:27