vue/require-explicit-emits - defineModel not supported
What did you do?
<script setup lang="ts">
defineModel<string>();
</script>
<template>
<input @input="$emit('update:modelValue', $event.target.value)" />
</template>
This causes warning/error: The "update:modelValue" event has been triggered but not declared on defineEmits.
Is this the recommended usage? I'd rather do this with defineModel:
<script setup lang="ts">
const modelValue = defineModel<string>();
</script>
<template>
<input @input="modelValue = $event.target.value" />
<!-- or even better: -->
<input v-model="modelValue" />
</template>
What about rest of cases, where you use it with $emit ? its still doesnt work as IMHo suppose to work, meaning if you use defineModel you expect to have interface api modelValue and emit update:modelValue defined, so eslint should not scream about it. Its there, explained in vue docs, its just eslint-plugin-vue does not support it
This is still relevant for me. As a use case, reusable components leveraging UI libraries tend to define their own models while passing them to the UI component as well. Example with a ConfirmDialog :
<script setup lang="ts">
defineModel<boolean>('visible')
const emit = defineEmits<{
'submit': [name: string]
}>()
const name = ref('')
function handleSubmit() {
emit('submit', name.value)
}
</script>
<template>
<!-- Dialog is a UI component from PrimeVue -->
<Dialog
:visible="visible"
@update:visible="$emit('update:visible', $event)">
<form @submit="handleSubmit">
<input v-model="name" type="text" />
<div>
<Button
label="Cancel"
@click="$emit('update:visible', false)" />
<Button
label="Create"
type="submit" />
</div>
</form>
</Dialog>
</template>
@corentind59 See my comment above; you could rewrite this as follows:
<script setup lang="ts">
const visible = defineModel<boolean>('visible')
const emit = defineEmits<{
'submit': [name: string]
}>()
const name = ref('')
function handleSubmit() {
emit('submit', name.value)
}
</script>
<template>
<!-- Dialog is a UI component from PrimeVue -->
<Dialog
:visible="visible"
@update:visible="visible = $event">
<form @submit="handleSubmit">
<input v-model="name" type="text" />
<div>
<Button
label="Cancel"
@click="visible = false" />
<Button
label="Create"
type="submit" />
</div>
</form>
</Dialog>
</template>