v-model on a Component
In the quiz, Quantity got the count as a prop and asked for changes with two events. A component that edits one value of its parent is so common that Vue has a shortcut for it: v-model, which you know from text fields, works on your own components too. Here's a component for choosing the size of a cup:
<SizePicker v-model="size" />In the component, defineModel() gives you that value as a ref:
<script setup>
const size = defineModel();
</script>
<template>
<div class="sizes">
<button :class="{ chosen: size === 'regular' }" @click="size = 'regular'">Regular</button>
<button :class="{ chosen: size === 'large' }" @click="size = 'large'">Large</button>
</div>
</template>size looks like the component's own ref, but it isn't. Reading it gives the parent's size. Changing it emits an event, which v-model in the parent catches, and it changes the parent's size. So the data still lives in one place, the parent, and the component didn't have to declare a prop and an event. (Under the hood, that's what v-model on a component is: a prop named modelValue and an event named update:modelValue, which defineModel() declares for you.)
In the script, it's a ref like any other, size.value. And defineModel() takes the same options as a prop, for example defineModel({ type: String, required: true }).
Instructions
- 1
Connect
Quantityto thecountofApp.vuewithv-modelanddefineModel(). The count shows between the buttons, the buttons change it, and the total changes with it. - 2
The count mustn't drop below 1: when it's 1, the − button is disabled (
:disabled).