I find myself spending very little time enjoying Vue. Which is not to say I hate it, but that I don't have a lot of fun with it — I've reached a sort of intellectual detente with the framework, and most of my "fun frontend time" is spent in pure functional TypeScript. But I was delighted to discover a change in Vue 3.4 that makes life 2% better (and I do not mean that to damn with faint praise — 2% is a lot!).


Historically, declaring a component with a value that can/should be updated requires a slew of boilerplate:

<template>
  <input
    type="text"
    :value="modelValue"
    @input="
      emit('update:modelValue', ($event.target as HTMLInputElement).value)
    "
  />
</template>

<script lang="ts" setup>
defineProps<{
  modelValue: string;
}>();

defineEmits<{
  "update:modelValue": string;
}>();
</script>

Vue 3.4 shipped support for the glorious defineModel macro, which makes this all much simpler:

<template>
  <input
    type="text"
    v-model="modelValue"
  />
</template>

<script lang='ts' setup>
defineModel<string>();
</script>

This is not paradigm-shifting, but it is both quite nice and conceptually clarifying. I'm very grateful for the addition, and excited to slowly backport a whole bunch of boilerplate.

Lightning bolt
Subscribe to my newsletter

I publish monthly roundups of everything I've written, plus pictures of my corgi.
© 2024 Justin Duke · All rights reserved · have a nice day.