The use of v-model in vue3 components and in-depth explanation

The use of v-model in vue3 components and in-depth explanation

Use two-way binding data in v-model input

In Vue, we often use v-model to bind the input value of the input box. Everyone should know the simple implementation principle of binding the value through v-bind and dynamically changing the bound value in combination with the @input input event to achieve two-way binding. The following is the Vue3 implementation code:

<template>
   <input type="text" :value="tryText" @input="handelInput">
   <h2>{{tryText}}</h2>
</template>

<script>
import { ref} from "vue"
    export default {
        setup(){
            let tryText = ref("default input value")
            function handelInput(e) {
                tryText.value = e.target.value; //Data access and modification defined by ref needs to be done through .value
            }
            return {
                tryText,
                handelInput
            }
        }
    }
</script>

I believe everyone often uses v-model in ipnut. Now let's take a look at how to use v-model in components and what its role is.

v-model in components

How to use v-model in components? Let's simply implement

Parent Component

<template>
  <!-- Component binding v-model -->
  <hy-input v-model="message"></hy-input>
  <h2>{{message}}</h2>
</template>

<script>
import { ref } from '@vue/reactivity'
import HyInput from "../components/HyInput.vue"
export default {
  components: {HyInput },
    setup(){
        let message = ref("嘿嘿嘿ヽ(*^ー^)(^ー^*)ノ")
        return {
            message,
        }
    }
}
</script>

Subcomponents

<template>
   <button @click="handelClick">O(∩_∩)O Haha~</button>
   <br>
</template>

<script>
    export default {
        props:{
            modelValue:String,
        },
        emits:['update:modelValue'],
        setup(props,context){
            function handelClick() {
                context.emit("update:modelValue","O(∩_∩)O哈哈~")
            }
        
            return {
                handelClick,
            }
        }
    }
</script>

Seeing this, we may have some doubts as to why we need to launch events? Why is there a default props receiving value? Don't worry, we will understand it from the implementation principle.

In this way, we can change the message data in the parent component by clicking the button of the child component. This is a simple implementation of two-way data binding v-model in a component.

Since it is a two-way binding, let's make a bold guess whether it is similar to the implementation principle in input? Let’s look at how it works.

Parent Component

<template>
  <!-- Principle -->
  <hy-input :modelValue="message" @update:modelValue="message = $event"></hy-input>
  <h2>{{message}}</h2>
</template>

<script>
import { ref } from '@vue/reactivity'
import HyInput from "../components/HyInput.vue"
export default {
  components: {HyInput },
    setup(){
        let message = ref("嘿嘿嘿ヽ(*^ー^)(^ー^*)ノ")
        return {
            message,
        }
    }
}
</script>

The subcomponent remains unchanged

<template>
   <button @click="handelClick">O(∩_∩)O Haha~</button>
   <br>
</template>

<script>
    export default {
        props:{
            modelValue:String,
        },
        emits:['update:modelValue'],
        setup(props,context){
            function handelClick() {
                context.emit("update:modelValue","O(∩_∩)O哈哈~")
            }
        
            return {
                handelClick,
            }
        }
    }
</script>

The results show that it is indeed possible

In this way, we can understand the emission events and default received values ​​in child components. The basic implementation principle is: the parent component passes values ​​to the child component, and the child component receives them through props. However, when the data needs to be modified in the child component, we tell the parent component by emitting an event, and then the parent component receives the passed value and modifies it. In fact, it is the communication between parent and child components, but Vue helps us make a simple encapsulation.

ps: By default, the data bound to v-model needs to be read in the subcomponent using modelValue to receive the emission event. The default name is update:modelValue. If you want to bind multiple values ​​or use a custom name, please see the other writing methods below.

ps: You cannot modify the data by modifying props. First of all, this is a particularly bad development habit. Then we know that the characteristics of props are only responsible for transferring data. Modifying props cannot achieve the desired effect. We should notify the parent component to update the data, which is the best practice.

Other ways to write

How can we implement bidirectional binding between the input in our child component and the parent component? And what if you need to pass multiple two-way binding data? What about custom names?
Parent Component

<template>
  <!-- Component binding v-model -->
  <hy-input v-model="message" v-model:text="inputText"></hy-input>
  <h2>{{message}}</h2>
  <h2>{{inputText}}</h2>
</template>

<script>
import { ref } from '@vue/reactivity'
import HyInput from "../components/HyInput.vue"
export default {
  components: {HyInput },
    setup(){
        let message = ref("嘿嘿嘿ヽ(*^ー^)(^ー^*)ノ")
        let inputText = ref("嘻嘻嘻嘻")
  
        return {
            message,
            inputText
        }
    }
}
</script>

Subcomponents

<template>
   <button @click="handelClick">O(∩_∩)O Haha~</button>
   <br>
   <input type="text" v-model="customText">
   <br>
</template>

<script>
import {computed} from "vue"
    export default {
        props:{
            modelValue:String,
            text:String
        },
        emits:['update:modelValue',"update:text"],
        setup(props,context){
            function handelClick() {
                context.emit("update:modelValue","O(∩_∩)O哈哈~")
            }
            let customText = computed({
                set(value){
                    context.emit("update:text",value)
                },
                get(){
                    return props.text
                }
            })

            return {
                handelClick,
                customText,
            }
        }
    }
</script>

Multiple binding values ​​and renaming v-model:text="inputText" The props in the subcomponent is directly text The emission event name is update:text
Here we see that in order to realize the bidirectional binding of the input box v-model in the child component to the parent component, we need to use the computed property to achieve it. Some students may want to directly bind the text in props, right? As mentioned above, if you only read, you can bind, but when you modify it, you need to notify the parent component to update the data by emitting events (you cannot modify the value in props, you can only read!!!). So in the calculated properties, we emit events in the set to update the parent component data, and when reading, we just read the value in props directly.

Summarize

This is the end of this article about the use and explanation of v-model in vue3 components. For more relevant vue3 component v-model usage content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Example code of vue custom component to implement v-model two-way binding data
  • Detailed explanation of the difference between v-model directive and .sync modifier in Vue
  • A brief discussion on the principle of Vue's two-way event binding v-model
  • Vue uses v-model to encapsulate the entire process of el-pagination components
  • Basic implementation method of cross-component binding using v-model in Vue
  • Problems and solutions encountered when using v-model to two-way bind the values ​​of parent-child components in Vue
  • Solution for Vue form input box not supporting focus and blur events
  • Detailed usage of Vue's form input component using custom events [Date component and currency component]
  • Example code for Vue form input binding
  • Vue form input formatting Chinese input method abnormality
  • Vue form input binding v-model

<<:  How to solve the error of connecting to the database when ServerManager starts

>>:  CentOS IP connection network implementation process diagram

Recommend

How to implement one-click deployment of nfs in linux

Server Information Management server: m01 172.16....

Detailed tutorial on using the Prettier Code plugin in vscode

Why use prettier? In large companies, front-end d...

MySQL 5.7.18 installation tutorial and problem summary

MySQL 5.7.18 installation and problem summary. I ...

A brief discussion on several situations where MySQL returns Boolean types

mysql returns Boolean type In the first case, ret...

Detailed explanation of the knowledge points of using TEXT/BLOB types in MySQL

1. The difference between TEXT and BLOB The only ...

VMware workstation 12 install Ubuntu 14.04 (64 bit)

1. Installation Environment Computer model: Lenov...

Introduction to Vue3 Composition API

Table of contents Overview Example Why is it need...

Use pure JS to achieve the secondary menu effect

This article example shares the specific code of ...

Summary of pitfalls of using nginx as a reverse proxy for grpc

background As we all know, nginx is a high-perfor...

Element uses scripts to automatically build new components

Table of contents background How does element-ui&...

Tips for importing csv, excel or sql files into MySQL

1. Import csv file Use the following command: 1.m...

How to implement a lucky wheel game in WeChat applet

I mainly introduce how to develop a lucky wheel g...