How to import emits interface
Vue version
3.3.7
Link to minimal reproduction
Steps to reproduce
Similar to issue #4294
component.ts: export interface Base { (e: "change", id: number): void }
Comp.vue import { Base } from ./component.ts
interface Emits extends Base { (e: "unChange", id: number): void }
const emit = defineEmits
emit(change, 1)
What is expected?
Component registers change as possible event, no errors/warnings raised.
What is actually happening?
[Vue warn]: Component emitted event "change" but it is neither declared in the emits option nor as an "onChange" prop.
System Info
No response
Any additional comments?
No response
You are using emit
incorrectly. emit
is used for child components to send events to their parent components.
Therefore, you need to declare the change function in the parent component.
One more thing, you have defined an unchange
function in the Emit
interface. This means that in emits('func', value)
, you should use the same name, like emits('unChange', count.value)
.
The correct code is as follows:
Comp.vue
<script setup lang="ts">
import { ref } from 'vue'
import { BaseEmits } from './composable'
interface Emits extends BaseEmits {
(e: 'unChange', id: number): void
}
const emits = defineEmits<Emits>()
const count = ref(0)
const clickEvent = () => {
count.value += 1
emits('unChange', count.value)
}
</script>
<template>
<button type="button" @click="clickEvent">Count: {{ count }}</button>
</template>
App.vue
<script setup lang="ts">
import { ref } from 'vue'
import Comp from './components/Comp.vue'
const msg = ref('Hello World!')
const handleChange = () => {
console.log('KUN IS THE CUTEST!')
// Something code you want to execute here
}
</script>
<template>
<h1>{{ msg }}</h1>
<Comp @un-change="handleChange" />
</template>
BTW, In 3.3+, you can use more succinct syntax
const emit = defineEmits<{
change: [id: number]
update: [value: string]
}>()
see: https://vuejs.org/guide/typescript/composition-api.html#typing-component-emits
Duplicate of https://github.com/vuejs/core/issues/8465
Code below seems to work
type Emits = BaseEmits & { (e: 'unChange', id: number): void }
You're welcome! I didn't know about this usage either.
Before the fix gets merged, you can use https://github.com/unplugin/unplugin-vue-complex-types as a temporal solution.