vue3+ts组件库:实现input组件v-model效果踩坑

思路:将组件上绑定的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)
        }
      })

 

可以通过在组件中使用`v-model`指令来实现双向数据绑定。在 Vue3 中,可以使用 TypeScript 类型来定义一个组件的 prop 和 data。 具体实现方法如下: 1. 在组件中定义一个`username`的 prop,类型为`string`。 ``` props: { username: { type: String } }, ``` 2. 在组件中定义一个 emit 事件,将组件内部的`username`状态改变时的值,通过该事件发送给父组件。 ``` methods: { updateUsername(event: Event) { this.$emit('update:username', (event.target as HTMLInputElement).value); } } ``` 3. 在模板中使用`v-model`指令将组件内部的`username`状态和父组件传入的`username` prop 进行绑定。 ``` <template> <input type="text" v-model="username" @input="updateUsername"> </template> <script> import { defineComponent } from 'vue'; export default defineComponent({ props: { username: { type: String } }, methods: { updateUsername(event: Event) { this.$emit('update:username', (event.target as HTMLInputElement).value); } } }); </script> ``` 上述代码中,当在父组件中使用该组件时,可以通过`v-model`指令将组件内部的`username`状态和父组件中的`username` prop 绑定起来。 例如: ``` <template> <div> <CustomInput v-model:username="username" /> <p>{{ username }}</p> </div> </template> <script> import { defineComponent, ref } from 'vue'; import CustomInput from './CustomInput.vue'; export default defineComponent({ components: { CustomInput }, setup() { const username = ref(''); return { username }; } }); </script> ``` 上述代码中,当用户在 `CustomInput` 组件中输入内容时,`username` 的值会同步更新,最终在父组件中渲染出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值