vue2 Vue3 v-model principle

Interview question: please explain the principle of v-model

v-model can act on both form elements and custom components. In either case (vue2, vue3), it is a syntax sugar and will eventually generate an attribute and an event.

When it acts on a form element, vue will generate appropriate attributes and events according to the type of form element. For example:

  • text and textarea elements use value property and input events;
  • checkbox and radio use checked property and change events;
  • The select field takes value as a prop and change as an event.

For custom components

vue2

v-model can also act on custom components. When it acts on custom components, it will generate a value attribute and input event by default.

Subcomponent HelloWorld

This sub component only implements the function of a simple counter, and then the event name I distribute upward is update:value. But vue2 if you use v-model, you 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 code

APP to use

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

result:

Analyzing virtual dom results

vue2's virtual dom is viewed by using this in mounted_ Vnode, and then view componentOptions to view the properties passed by the component.

Developers can modify the sub component HelloWorld by changing the generated properties and events through the model configuration of the component

<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", // The default is input
  },
  methods: {
    change(val) {
      this.$emit("change", val);
    },
  },
};
</script>
Copy code

Parent component modification

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

effect

vue3

v-model can also act on custom components. When it acts on custom components, it will generate a modelValue property and onUpdate:modelValue event by default.

Subcomponent 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 code

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 code

result

Virtual dom analysis

vue3 uses ` ` getCurrentInstance 'to view the virtual dom, and uses props in children to view the property transfer

difference

Both vue2 and vue3 have v-model. The principle is to generate an attribute and an event, but there are some differences.

. sync modifier

The. sync modifier in vue3 is removed, and its function can be replaced by the parameters of v-model

For example:

<!-- vue2 -->
<Comp :title="inputVal" @update:title="inputVal = $event" />
<!-- Abbreviated as -->
<Comp :title.sync="inputVal" />

<!-- vue3 -->
<Comp :title="inputVal" @update:title="inputVal = $event" />
<!-- Abbreviated as -->
<Comp v-model:title="inputVal" />
Copy code

Multiple v-model s

vue3 allows you to write multiple v-models, which also strongly shows that v-model is a syntax sugar, which just helps you reduce the amount of code, that's all. 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 code

##v-model modifier

vue2.x is a self-contained modifier, but in the 3.x version, you can customize the modifier. The modifier in 3.x will be passed to the sub component as an attribute, and a modelModifiers attribute will be generated in the attribute. If this modifier exists, there will be a corresponding modifier and it is true. If it is not passed, it is undefined.

Modifying Comp subcomponents

<script setup>
import { ref, } from 'vue'
 const props =  defineProps({
    modelValue: Number,
    modelModifiers: { 
      default: () => ({})
    }
  })

 const emits = defineEmits(['update:modelValue']);
  
  const change = (val) => {
    // If the modifier 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 code

Parent component usage

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

effect

vue3 test code address: vue2 test code address was deleted due to forgetting to log in 🤣🤣🤣

Keywords: Javascript Front-end Algorithm

Added by geraldpolar on Fri, 19 Nov 2021 03:04:40 +0200