Issue
This Content is from Stack Overflow. Question asked by lizcodecode
As title,when I typed ’emit(update:${propsName}
, evt);’ in CustomInput component,the error goes ‘Argument of type ‘update:${string}
‘ is not assignable to parameter of type ‘”update:modelValue” | “update:lastName”‘.’
Any help would be much appreciated!
//App.js
<script setup lang="ts">
import { ref } from "vue";
import CustomInputVue from "./components/CustomInput.vue";
let firstName = ref("");
let lastName = ref("");
</script>
<template>
<CustomInputVue
v-model.no-whiteSpace="firstName"
v-model:lastName="lastName"
/>
</template>
//CustomInput.vue
<script setup lang="ts">
const props = defineProps({
modelValue: {
type: String,
required: false,
},
lastName: {
type: String,
required: false,
},
modelModifiers: {
type: Object as any,
required: false,
},
});
const emit = defineEmits(["update:modelValue", "update:lastName"]);
const emitValue = (propsName: string, e: Event) => {
let evt = (e.target as HTMLInputElement).value;
if (props.modelModifiers["no-whiteSpace"]) {
evt = evt.replace(/s/g, "");
}
emit(`update:${propsName}`, evt); =>
};
</script>
<template>
<label class="block text-gray-700 text-sm font-bold mb-2" for="firstName">
First Name
</label>
<input
class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none mb-4"
id="firstName"
type="text"
placeholder="First Name"
:value="modelValue"
@input="emitValue('modelValue', $event)"
/>
<label class="block text-gray-700 text-sm font-bold mb-2" for="lastName">
Last Name
</label>
<input
class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none"
id="lastName"
type="text"
placeholder="Last Name"
:value="lastName"
@input="$emit('update:lastName', ($event.target as HTMLFormElement).value)"
/>
</template>
<style scoped></style>
Solution
The problem is that the update:${propsName}
type is greater then "update:modelValue" | "update:lastName"
(aka update:${"modelValue" | "lastName"}
) you are allowed to use in emit
Reduce it down, and the problem will be solved
const emitValue = (propsName: "modelValue" | "lastName", e: Event) => {
let evt = (e.target as HTMLInputElement).value;
if (props.modelModifiers["no-whiteSpace"]) {
evt = evt.replace(/\s/g, "");
}
emit(`update:${propsName}`, evt);
};
You are using Event and event.target, that is likely to be bad code.
const lastName = ref(props.lastName || "");
function emitName() {
let newValue = lastName.value;
// it's optional prop so "?."
if (props.modelModifiers?.["no-whiteSpace"]) {
newValue = newValue.replace(/\s/g, "");
}
emit("update:lastName", newValue)
}
const imputEl = ref<HTMLImputElement>() // if you need it
...
<imput v-model="lastName" ref="imputEl">
BTW consider using type-based syntax for props and emits, it compiles into same code internally
const props = defineProps<{
modelValue?: string,
lastName?: string,
modelModifiers?: {'no-whiteSpace'?: boolean},
}>();
const emit = defineEmits<{
(event: "update:modelValue" | "update:lastName", data: string): void;
}>();
This Question was asked in StackOverflow by lizcodecode and Answered by Dimava It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.