Vue3组合式API如何自定义v-model绑定的prop?
Vue3组合式API中自定义v-model的prop方法
在Vue2中,v-model默认绑定
valueprop,但也可以自定义其他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名**的语法实现自定义绑定。组件内部只需三步:
- 定义接收的目标prop
- 定义对应格式的更新事件(固定为
update:自定义prop名) - 触发更新时通过
$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
相关产品推荐
相关产品推荐

