vue组件实现v model
Vue 组件实现 v-model
在 Vue 中,v-model 是一个语法糖,用于在表单元素上实现双向数据绑定。在自定义组件中,可以通过 model 选项和 $emit 方法实现类似的功能。
基本实现方式
自定义组件中需要定义一个 value prop 用于接收父组件传递的值,并通过 input 事件将修改后的值传递回父组件。
// 子组件
Vue.component('custom-input', {
props: ['value'],
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
`
})
父组件中使用 v-model 绑定数据:
// 父组件
new Vue({
el: '#app',
data: {
message: ''
},
template: `
<div>
<custom-input v-model="message"></custom-input>
<p>{{ message }}</p>
</div>
`
})
使用 model 选项
如果需要修改默认的 prop 和事件名称,可以使用 model 选项:
Vue.component('custom-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
:checked="checked"
@change="$emit('change', $event.target.checked)"
>
`
})
父组件中使用方式不变:
<custom-checkbox v-model="isChecked"></custom-checkbox>
计算属性实现复杂逻辑
对于需要复杂处理的场景,可以在组件内部使用计算属性:
Vue.component('custom-input', {
props: ['value'],
computed: {
internalValue: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
},
template: `
<input v-model="internalValue">
`
})
修饰符处理
自定义组件可以支持 v-model 修饰符,通过 model 选项的 modifiers 属性访问:
Vue.component('custom-input', {
props: ['value', 'modifiers'],
created() {
console.log(this.modifiers) // 例如 { lazy: true }
},
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
`
})
使用带修饰符的 v-model:
<custom-input v-model.lazy="message"></custom-input>
Vue 3 中的变化
在 Vue 3 中,v-model 的实现有所变化,支持多个 v-model 绑定:
// 子组件
app.component('custom-input', {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
`
})
父组件中使用:
<custom-input v-model="message"></custom-input>
对于多个 v-model 绑定:
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
></user-name>
子组件需要分别处理:
app.component('user-name', {
props: {
firstName: String,
lastName: String
},
emits: ['update:firstName', 'update:lastName'],
template: `
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
>
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
>
`
})






