Subscribe on changes!

Deprecate `emit` and `v-model` in the next major version

avatar
Jun 18th 2023

Currently, to define props and events, we've got props, emits, defineProps, defineEmits, and possible defineModel, each of them has different syntaxes, even as a Vue veteran, that's a lot to digest and remember. Which deviates from Vue's design philosophy of being simple and beginner-friendly, as a long-time Vue user, I don't feel Vue is going in the right direction in this regard.


It appears to me that props can do all emit + v-model can do but in a more explicit, less magical, and more type-friendly way. I forgot how many times I rewrote v-model to :prop + @event because emit and v-model could not meet the needs.

To name a few:

// 1. `visibleChange` can only be listened to optionally.
// 2. The listener of `visibleChange` can not specify the return type.
defineEmits<{ visibleChange: [visible: boolean] }>()

// 1. Can specify if `onVisibleChange` is required.
// 2. Can specify the return type of `onVisibleChange`.
defineProps<{ onVisibleChange?(visible: boolean): void }>()

In the child component, we use @event="onVisibleChange($event)" instead of @event="$emit('visibleChange', $event)".

In the parent component, @visible-change="visible = $event" is compiled to onVisibleChange="$event => visible.value = $event", so the v-on/@ directive still works.

Too many options to achieve the same functional goal create code inconsistencies and are a huge maintenance burden e.g. tooling support, more eslint rules have to be created and applied, etc. I suggest deprecating emit and v-model in the next major version.

If there're other emit use cases that are not covered by props, please let me know.

Ref: Naive UI's author discourages emit usage.