前言
在 Vue 开发中,v-model 是实现表单双向绑定的核心指令,日常开发中我们常用来绑定输入框、单选框等原生表单元素。但在 Vue3 中,v-model 经过全面升级,不仅支持自定义组件的双向绑定,还能实现多绑定值、自定义修饰符、参数化 v-model 等高级特性,是封装高复用性组件(如自定义表单组件、弹窗、滑块等)的必备技能。
本文从 Vue3 v-model 核心原理讲起,由浅入深讲解基础自定义 v-model、多 v-model 绑定、自定义修饰符、带参数的 v-model 四大高级用法,搭配可直接运行的实战代码,帮助理解 Vue3 自定义 v-model 的底层逻辑和实战技巧。
一、Vue3 中 v-model 核心原理
首先要明确:Vue3 的 v-model 本质是语法糖,它默认等价于:
- 向子组件传递
modelValue属性 - 监听子组件触发的
update:modelValue事件
这是和 Vue2 最大的区别(Vue2 默认是 value 属性和 input 事件),也是自定义 v-model 的基础。
原生 v-model 等价写法:
<!-- 原生 v-model 写法 -->
<input v-model="name" />
<!-- 等价拆解写法 -->
<input :value="name" @input="name = $event.target.value" />
组件 v-model 等价写法:
<!-- 组件 v-model 写法 -->
<CustomInput v-model="name" />
<!-- Vue3 等价拆解写法 -->
<CustomInput :modelValue="name" @update:modelValue="name = $event" />
掌握这个原理,自定义 v-model 就变得非常简单!
二、基础版:自定义组件单 v-model 绑定
这是最常用的场景:封装一个自定义输入组件,实现和原生 input 一样的双向绑定效果。
1. 子组件实现(CustomInput.vue)
<template>
<div>
<input
type="text"
:value="modelValue"
@input="handleInput"
placeholder="请输入内容"
/>
</div>
</template>
<script setup>
// 接收父组件的 modelValue 属性
const props = defineProps({
modelValue: {
type: String,
default: ''
}
})
// 定义触发事件(Vue3 setup 语法糖必须用 defineEmits)
const emit = defineEmits(['update:modelValue'])
// 输入时触发事件,向父组件传递最新值
const handleInput = (e) => {
emit('update:modelValue', e.target.value)
}
</script>
<style scoped>
.custom-input input {
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
outline: none;
}
.custom-input input:focus {
border-color: #409eff;
}
</style>

