SoFunction
Updated on 2025-04-04

Methods for implementing bidirectional data binding in vue3

In Vue 3, two-way data binding is mainly throughv-modelInstruction implementation.v-modelis a syntactic sugar, which actually combines internallyv-bindandv-onInstructions to implement two-way binding of data. The following is a detailed introduction to the implementation principles and usage methods of bidirectional data binding in Vue 3.

The basic principles of two-way data binding

  • v-bindDirective: Used to bind data to an element's attribute.
  • v-onDirective: Used to listen to user input events and update data.

v-modelHow it works

v-modelIt's actually a syntactic sugar, which does the following things internally:

  • Bind data:usev-bindBinding data to element'svalueproperty.
  • Listen to input events:usev-onmonitorinputEvent, and update data when the event is triggered.

Basic usage

<template>
  <div>
    <input v-model="message" />
    <p>{{ message }}</p>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const message = ref('Hello, Vue 3!');
</script>
<style scoped>
/* Your style */
</style>

In this example,v-modelThe following functions are implemented:

  • Bind datainputElementalvalueProperties binding tomessage
  • Listen to input events: When the user enters content in the input box,messageThe value of .

Internal implementation

v-modelThe internal implementation can be broken down into the following two parts:

v-bindBind data:

<input :value="message" />

v-onListen to input events:

<input :value="message" @input="message = $" />

Customize the componentv-model

Use in custom componentsv-modelWhen it is done manuallyv-modelbehavior. Usually bymodelValueProperties andupdate:modelValueEvents are implemented.

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;ChildComponent v-model="message" /&gt;
    &lt;p&gt;{{ message }}&lt;/p&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue';
import ChildComponent from './';
const message = ref('Hello, Vue 3!');
&lt;/script&gt;
&lt;style scoped&gt;
/* Your style */
&lt;/style&gt;
&lt;!--  --&gt;
&lt;template&gt;
  &lt;input :value="modelValue" @input="$emit('update:modelValue', $)" /&gt;
&lt;/template&gt;
&lt;script setup&gt;
defineProps(['modelValue']);
defineEmits(['update:modelValue']);
&lt;/script&gt;
&lt;style scoped&gt;
/* Your style */
&lt;/style&gt;

Parent component

  • usev-modelWillmessageBind toChildComponent
  • v-modelActually it is:modelValueand@update:modelValuesyntax sugar.

Subcomponents

  • usemodelValueThe property receives the value passed by the parent component.
  • use@inputEvent listens for changes in the input box and passes$emittriggerupdate:modelValueEvent, passing the new value back to the parent component.

Bidirectional binding of multiple values

If you need to implement two-way binding of multiple values ​​in a child component, you can use multiplev-modelBind.

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;ChildComponent v-model:title="title" v-model:content="content" /&gt;
    &lt;p&gt;Title: {{ title }}&lt;/p&gt;
    &lt;p&gt;Content: {{ content }}&lt;/p&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref } from 'vue';
import ChildComponent from './';
const title = ref('Title');
const content = ref('Content');
&lt;/script&gt;
&lt;style scoped&gt;
/* Your style */
&lt;/style&gt;
&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;input :value="title" @input="$emit('update:title', $)" placeholder="Title" /&gt;
    &lt;textarea :value="content" @input="$emit('update:content', $)" placeholder="Content"&gt;&lt;/textarea&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
defineProps(['title', 'content']);
defineEmits(['update:title', 'update:content']);
&lt;/script&gt;
&lt;style scoped&gt;
/* Your style */
&lt;/style&gt;

Parent component

  • usev-model:titleandv-model:contentBind separatelytitleandcontent
  • v-model:titleActually it is:titleand@update:titlesyntactic sugar,v-model:contentSame thing.

Subcomponents

  • usetitleandcontentThe property receives the value passed by the parent component.
  • use@inputEvent listens for changes in the input box and passes$emittriggerupdate:titleandupdate:contentEvent, passing the new value back to the parent component.

Through these methods, Vue 3 provides a flexible and powerful two-way data binding mechanism, making data synchronization and updates easier and more intuitive.

More data binding methods

In Vue 3, exceptv-modelIn addition to the two-way data binding implemented, there are also a variety of data binding methods for different scenarios and requirements. Here are some common data binding methods and how to use it:

1. One-way data binding (v-bind)

v-bindUsed to bind data to the attributes of an element, implementing one-way binding from data to view.

<template>
  <div>
    <img v-bind:src="imageUrl" alt="Image">
    <p v-bind:title="tooltip">Hover over me</p>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const imageUrl = ref('/');
const tooltip = ref('This is a tooltip');
</script>

2. Dynamic binding (v-bindDynamic attributes)

v-bindYou can also dynamically bind attribute names.

<template>
  <div>
    <span :[dynamicAttr]="value">Dynamic Binding</span>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const dynamicAttr = ref('title');
const value = ref('This is a dynamic attribute');
</script>

3. Event binding (v-on)

v-onUsed to bind event processors to implement one-way binding from view to data.

<template>
  <div>
    <button @click="increment">Increment</button>
    <p>Count: {{ count }}</p>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => {
  ++;
};
</script>

4. Calculate properties (computed)

Computational properties are used to dynamically calculate new data based on other data and are responsive.

<template>
  <div>
    <input v-model="firstName" placeholder="First Name">
    <input v-model="lastName" placeholder="Last Name">
    <p>Full Name: {{ fullName }}</p>
  </div>
</template>
<script setup>
import { ref, computed } from 'vue';
const firstName = ref('');
const lastName = ref('');
const fullName = computed(() => {
  return `${} ${}`;
});
</script>

5. Listener (watch)

Listeners are used to listen for changes in data and perform specific operations when the data changes.

&lt;template&gt;
  &lt;div&gt;
    &lt;input v-model="searchQuery" placeholder="Search"&gt;
    &lt;p&gt;Results: {{ results }}&lt;/p&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { ref, watch } from 'vue';
const searchQuery = ref('');
const results = ref([]);
watch(searchQuery, (newQuery) =&gt; {
  // Simulate asynchronous requests  setTimeout(() =&gt; {
     = newQuery ? [newQuery, 'Result 2', 'Result 3'] : [];
  }, 500);
});
&lt;/script&gt;

6. Dynamic Components (<component>)

Dynamic components are used to dynamically switch components based on data.

<template>
  <div>
    <button @click="currentComponent = 'ComponentA'">Show Component A</button>
    <button @click="currentComponent = 'ComponentB'">Show Component B</button>
    <component :is="currentComponent"></component>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import ComponentA from './';
import ComponentB from './';
const currentComponent = ref('ComponentA');
</script>

7. Slot (slot)

Slots are used to insert content into components to enable component reuse and customization.

<!--  -->
<template>
  <div>
    <ChildComponent>
      <p>This is slot content</p>
    </ChildComponent>
  </div>
</template>
<script setup>
import ChildComponent from './';
</script>
<!--  -->
<template>
  <div>
    <slot></slot>
  </div>
</template>
<script setup>
</script>

8. Custom commands (directive)

Custom directives are used to extend Vue's functionality to implement specific DOM operations.

&lt;template&gt;
  &lt;div&gt;
    &lt;p v-focus&gt;Focus me&lt;/p&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
import { directive } from 'vue';
// Define custom commandsdirective('focus', {
  mounted(el) {
    ();
  }
});
&lt;/script&gt;

Summarize

Vue 3 provides a variety of data binding methods, each with its specific usage scenarios and advantages. Understanding these different data binding methods can help you more flexibly handle various needs in development and build efficient and responsive web applications. Hope these examples and explanations help you!

This is the end of this article about how to implement two-way data binding in vue3. For more related content on vue3, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!