“This is the 12th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

Interview question: Please explain the principle of v-Model

The V-Model can be applied to either form elements or custom components, and in either case (vue2, vue3) it is a syntactic sugar that ultimately generates a property and an event.

When applied to a form element, VUE generates the appropriate attributes and events based on the type of form element being applied. Such as:

  • Text and Textarea elements are usedvalueThe property andinputEvents;
  • Checkbox and radio usecheckedThe property andchangeEvents;
  • The select field willvalueAs prop and willchangeAs an event.

For custom components

vue2

V-model can also be applied to custom components, and when applied to custom components, it generates a value property and an input event by default.

Subcomponents HelloWorld

This child component just implements the function of a simple counter, and THEN I send up the event name update:value. However, vue2 using v-Model will automatically change the event name to input.

<template> <div class="hello"> <button @click="change(value - 1)">-</button> <span>{{value}}</span> <button @click="change(value + 1)">+</button> </div> </template> <script> export default { name: "HelloWorld", props: { value: Number, }, methods: { change(val) { this.$emit("update:value", val); ,}}}; </script>Copy the code

The APP to use

<HelloWorld :value="inputVal" @update:value="inputVal = $event" />Equivalent to<HelloWorld v-model="inputVal" />
Copy the code

Results:

Analyze the virtual DOM results

Vue2 uses this._vnode in Mounted to view the virtual DOM, and then views componentOptions to view the properties passed by the component.

Developers can modify the child component HelloWorld by changing the generated properties and events through the component’s Model configuration

<template>
  <div class="hello">
    <button @click="change(number - 1)">-</button>
    <span>{{ number }}</span>
    <button @click="change(number + 1)">+</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld".props: {
    number: Number,},model: {
    prop: "number".// The default is value
    event: "change".// Default is input
  },
  methods: {
    change(val) {
      this.$emit("change", val); ,}}};</script>
Copy the code

Parent component modification

<HelloWorld v-model="inputVal" />
<! -- equivalent to -->
<HelloWorld :number="inputVal" @change="data=$event" />
Copy the code

The effect

vue3

V-model can also be applied to custom components, and when applied to custom components, by default it generates a modelValue property and an onUpdate:modelValue event.

Subcomponents Comp

<script setup>
import { ref, } from 'vue'
 const props =  defineProps({
    modelValue: Number
  })
 
 const emits = defineEmits(['update:modelValue']);
  
  const change = (val) = > {
    emits('update:modelValue', val)
  }
</script>
<template>                             
  <button @click="change(props.modelValue - 1)">
    -
  </button>
  <span>{{props.modelValue}}</span>
  <button @click="change(props.modelValue + 1)">
    +
  </button>
</template>
Copy the code

The parent component App

<script setup>
import { ref, getCurrentInstance } from 'vue'
 import Comp from './Comp.vue'
 
const msg = ref(123);
 const internalInstance = getCurrentInstance();
  console.log(internalInstance)
 
</script>

<template>                             
  <Comp v-model="msg"></Comp>Equivalent to<Comp :modelValue="msg" @update:modelValue="msg = $event"></Comp>
</template>
Copy the code

The results of

Virtual DOM analysis

Vue3 uses getCurrentInstance to look at properties passing in the children props

The difference between

Vue2 and VUe3 are both V-Models that generate an attribute and an event, but there are some differences.

.syncThe modifier

The. Sync modifier in vue3 has been removed and its functionality can be replaced by v-Model parameters

Such as:

<! -- vue2 --><Comp :title="inputVal" @update:title="inputVal = $event" /><! --><Comp :title.sync="inputVal" /><! -- vue3 --><Comp :title="inputVal" @update:title="inputVal = $event" /><! --><Comp v-model:title="inputVal" />
Copy the code

Multiple v – model

The fact that vuE3 allows you to write multiple V-models is a strong indication that v-models are just syntactic candy that reduces the amount of code you write, but nothing more. Vue2 cannot write multiple V-models

<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" /> <! -- is short for:  --> <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" :content="pageContent" @update:content="pageContent = $event" />Copy the code

# # v – model modifier

Vue2. X is a built-in modifier, but in 3.x, you can customize the modifier. Modifiers in 3.x are passed to child components as attributes, and a modelModifiers property is generated in the attributes. The presence of this modifier will have a corresponding modifier, and it will be true, if not passed, undefined.

Modify the Comp subcomponent

<script setup>
import { ref, } from 'vue'
 const props =  defineProps({
    modelValue: Number.modelModifiers: { 
      default: () = >({})}})const emits = defineEmits(['update:modelValue']);
  
  const change = (val) = > {
    // If range2 exists, add 1 and the subtraction will have no effect
    if(props.modelModifiers.range2){
      val ++;
    }
    emits('update:modelValue', val)
  }
</script>
<template>                             
  <button @click="change(props.modelValue - 1)">
    -
  </button>
  <span>{{props.modelValue}}</span>
  <button @click="change(props.modelValue + 1)">
    +
  </button>
</template>
Copy the code

Parent component use

<Comp v-model.range2="msg"></Comp>
Copy the code

The effect

Vue3 test code address: vue2 test code address, because I forgot to log in, it was deleted 🤣🤣🤣