defineModel() là macro (ổn định từ Vue 3.4) gói lại đúng cặp prop + emit mà trước đây phải khai báo tay, và trả về một ref hai chiều.
vue
<!-- before: declare both sides manually -->
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input :value="props.modelValue" @input="emit('update:modelValue', $event.target.value)">
</template>vue
<!-- after -->
<script setup>
const model = defineModel() // or defineModel('title') for v-model:title
</script>
<template>
<input v-model="model">
</template>Khác biệt đáng nói:
- Ghi model.value = x sẽ tự emit update:modelValue; đọc model.value lấy giá trị prop hiện tại. Không cần đồng bộ tay.
- Hỗ trợ nhiều model trên một component: defineModel('firstName'), defineModel('lastName') → v-model:first-name, v-model:last-name.
- Nhận option như prop thường: defineModel({ required: true, default: 0 }), và lấy modifier qua const [model, mods] = defineModel().
- Nếu cha không dùng v-model, ref này hoạt động như local state, nên component vẫn dùng được độc lập.