在 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)
}
}
}
}
缺点
- 无论是原生组件还是自定义组件都只能存在一个 v-model
- 繁琐
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"
/>