I have the following (atom) input component Element UI (Element Plus for vue 3) as base component.
atom/input/index.vue
<template>
<el-form-item :label="label">
<ElInput
:value="modelValue"
@input="$emit('update:modelValue', handleInputChange($event))"
>
<template v-if="prepend" #prepend>Http://</template>
<template v-if="append" #append>.com</template>
</ElInput>
</el-form-item>
</template>
<script setup lang="ts">
import { ElInput, ElFormItem } from "element-plus"
interface IInput {
label: string
modelValue: any
}
const { label, modelValue } = defineProps<IInput>()
const handleInputChange = (event: Event) => {
console.log(event)
return (event.target as HTMLInputElement).value
}
</script>
In my home component:
components/home.vue
<template>
<Input :label="'Book title'" v-model="title" />
<br/>
<h1>{{title}}</h1>
</template>
<script setup lang="ts">
import { ref } from "vue"
import Input from "./atom/input/index.vue"
const title = ref<string>("")
</script>
With the above code setup the component is displayed in correct form with its label.
But when I start typing in the input component I get the following error in my console.
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'value')
I've also logged the event in the console and it is returning the characters that I've typed.
Additionally I get error message of:
Argument of type 'string' is not assignable to parameter of type 'Event'.
In my code line : @input="$emit('update:modelValue', handleInputChange($event))"
Which I was able to remove my typecasting: handleInputChange(<Event | unknown>$event)
I also tried creating reusable input component with html input tag with same value and emit as above and it worked without any error.
Can anyone help me figure out what I'm missing here ?
Update:
As suggestion by Duannx I changed my return of the function:
const handleInputChange = (event: any) => {
return event
}
But now when I type in the input field the first character is replaced by second character, second character is replaced by third and so on.
Here is the reproduction of the issue in element ui playground:
CodePudding user response:
The input
event of the element plus input is passed a value (string | number
), not an Event
type. So you can use $event
directly as the value.
<ElInput
:value="modelValue"
@input="$emit('update:modelValue', $event)"
>
<template v-if="prepend" #prepend>Http://</template>
<template v-if="append" #append>.com</template>
</ElInput>
CodePudding user response:
I figured out that I have to make use of set and get method in computed property.
<template>
<el-form-item :label="label">
<ElInput
:autofocus="true"
:type="type"
:placeholder="placeholder"
:show-word-limit="showWordLimit"
:clearable="clearable"
:show-password="showPassword"
:suffix-icon="suffixIcon"
:prefix-icon="prefixIcon"
:size="size"
:max-length="maxLength"
:value="modelValue"
@input="$emit('update:modelValue', handleInputChange($event))"
>
<template v-if="prepend" #prepend>Http://</template>
<template v-if="append" #append>.com</template>
</ElInput>
</el-form-item>
</template>
<script setup lang="ts">
import { ElInput, ElFormItem } from "element-plus"
interface IInput {
label: string
type?: string
placeholder?: string
maxLength?: number
showWordLimit?: boolean
clearable?: boolean
showPassword?: boolean
suffixIcon?: any
prefixIcon?: any
size?: string
prepend?: any
append?: any
modelValue: any
}
const {
label,
type,
placeholder,
maxLength,
showWordLimit,
clearable,
showPassword,
suffixIcon,
prefixIcon,
size,
prepend,
append,
modelValue,
} = defineProps<IInput>()
const handleInputChange = (value: any) => {
return value
}
</script>