思路:将组件上绑定的v-model,分成:value和@input处理
在组件内,通过props接收外部传来的value,将该value与组件内<input>的value实现双向绑定
坑1:此时不能直接在<input>用v-model=“value”,因子组件不能直接修改props传的值
将v-model拆成:value与@input,用计算属性inputValue作为中间值来传递和修改value
inoutValue绑定:value
<template>
<div class="wrapper">
<input
type="text"
class="m-input"
v-bind="$attrs"
:value="inputValue"
>
</div>
</template>
//setup内定义计算属性
let inputValue=computed({
get(){
console.log('a'+props.value)
return props.value
},
set(value){}
})
接下来需要在<input>的@input触发时,通过改变inputValue,去改变父组件的value值。
首先为@input绑定方法,将输入值赋给inputValue
<template>
<div class="inline-container">
<input
type="text"
class="m-input"
v-bind="$attrs"
:value="inputValue"
@input="onInput"
>
</div>
</template>
//setup
const onInput=(event:Event):void=>{
inputValue.value=(<HTMLInputElement>event.target)?(<HTMLInputElement>event.target).value:""
}
坑2:获取event.target.value会报错没有value,因为event.target默认为HTMLElement类型,不一定有value属性,要做个断言<HTMLInputElement>
坑3:会提示event.target可能为null,可以用三元表达式做个判断
赋值触发inputValue的set方法,这时候去触发外部的@input,将输入值传给外部
//inputValue内:
set(value){
context.emit('input',value)
}
外部就可以通过v-model绑定了
<my-input v-model="count"></my-input>
整体的思路是这样
这里还有坑4:
当v-model绑定在组件而非<input>上时,并不会被编译成:value和@input,而是:modelValue和@update:modelValue,需要将前面思路中的:value和@input替换掉
<template>
<div class="inline-container">
<input
type="text"
class="m-input"
v-bind="$attrs"
:value="inputValue"
@input="onInput"
>
</div>
</template>
//setup内
const onInput=(event:Event):void=>{
inputValue.value=(<HTMLInputElement>event.target)?(<HTMLInputElement>event.target).value:""
}
let inputValue=computed({
get(){
console.log('a'+props.modelValue)
return props.modelValue
},
set(value){
context.emit('update:modelValue',value)
}
})