Parent component implements two-way binding
Use v-model in parent component:
<ChildComponent v-model="message" />
Equivalent to:
<ChildComponent :modelValue="message" @update:modelValue="val => message = val" />
:modelValue: Pass the value of message to the child component through props.
@update:modelValue: Send update value to the parent component via emit.
Subcomponents implement bidirectional binding
In order to support the v-model of the parent component, the child component needs:
1. Define props to receive data passed by the parent component.
2. Use emit to send update events.
<script setup> import { defineProps, defineEmits } from 'vue'; // Receive the modelValue passed by the parent componentdefineProps({ modelValue: String, // The value passed by the parent component}); // Define update eventdefineEmits(['update:modelValue']); const updateValue = (newValue) => { // Trigger event to notify the parent component to update data emit('update:modelValue', newValue); }; </script> <template> <input :value="modelValue" @input="updateValue($)" /> </template>
defineModel()
Starting from Vue 3.4, the recommended implementation is to use the defineModel() macro
<!-- --> <script setup> const model = defineModel() function update() { ++ } </script> <template> <div>Parent bound v-model is: {{ model }}</div> <button @click="update">Increment</button> </template>
The parent component can use v-model to bind a value:
template
<!-- --> <Child v-model="countModel" />
defineModel() returns a ref. It can be accessed and modified like other refs, but it can function as a two-way binding between the parent component and the current variable:
- Its .value is synchronized with the value of the v-model of the parent component;
- When it is changed by the child component, the value bound by the parent component will be triggered to be updated together.
This means you can also use v-model to bind this ref to a native input element, and easily wrap the native input element while providing the same v-model usage:
<script setup> const model = defineModel() </script> <template> <input v-model="model" /> </template>
The underlying mechanism
defineModel is a convenience macro. The compiler expands it to the following:
A prop named modelValue, with the value of the local ref synchronized;
An event named update:modelValue is triggered when the value of the local ref changes.
This article about this article about V-model implementing bidirectional binding of data is introduced here. For more related bidirectional binding of V-model data, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!