v-model of custom components (implementation principle of v-model)

v-model of custom component

By default, the v-model on the component utilizes a prop named value and an event named input.

According to the introduction of Vue's official website, Vue's two-way binding is a syntax sugar. Essentially
"Be responsible for listening to user input events to update data, and carry out some special processing for some extreme scenarios."

<input v-model="parentData">

Equivalent to:

<input
    :value="parentData"
    @input="parentData = $event.target.value"
>

Why is the above original writing only for input text?
vue official website is explained as follows:

v-model internally uses different attributes for different input elements and throws different events:

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

The following examples customize the component runoob input. The initial value of the num of the parent component is 100. Changing the value of the child component can update the num of the parent component in real time:

<div id="app">
    <runoob-input v-model="num"></runoob-input>
    <p>The number entered is:{{num}}</p>
</div>
<script>
Vue.component('runoob-input', {
    template: `
    <p>    <!--Contains a file named input Events-->
        <input
	         ref="input"
	         :value="value"
	         @input="$emit('input', $event.target.value)"
         >
     </p>
     `,
     props:['value'],
 })
new Vue({
    el: "app",
    data: {
        num: 100,
    }
})
</script>       


Since v-model passes in value by default, not checked, we need to use the model option for components with check boxes or radio boxes. The model option can specify the current event type and the incoming props. (that is, add a two-way binding of custom events to the component)

<div id="app">
    <base-checkbox v-model="lovingVue"></base-checkbox> 
     <div v-show="lovingVue"> 
        If the check box is checked, I will display it. 
    </div>
</div> 
<script>
// register
Vue.component('base-checkbox', {
 
  model: {
    prop: 'checked',
    event: 'change'  // onchange event
  },
  props: {
    checked: Boolean
  },
   
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})
// Create root instance
new Vue({
  el: '#app',
  data: {
    lovingVue: true
  }
})
</script>


The value of lovingVue in the instance will be passed to the checked prop, and the value of lovingVue will be updated when the change event is triggered.

The specific analysis is as follows:
In order to realize the two-way binding of adding custom events to components, we need to add a model object for our components and inform vue framework of the corresponding properties and events of this two-way binding in the model object.

The following example tells vue the underlying component to listen for the change event of the checked property.

model: {
    prop: 'checked',
    event: 'change'
  },

The specific steps of adding two-way binding of custom events to components are as follows:

  1. The first step is to add a model object to the component
model: {
    prop: 'checked',
    event: 'change'
  },
  1. The second step is to register the checked attribute in the props of the component
props:{
    checked: Boolean
}
  1. Step 3: modify the template and add the checkbox and the selected status description. It should be noted that you need to use the essential attribute binding and event coding that fully implements the v-model.
<input
    type="checkbox"
    :checked="checked"
    @change="$emit('change', $event.target.checked)"
>

4. Finally, when we use base checkbox in the template in APP.vue, we can realize the two-way binding of base checkbox components through v-model.

<base-checkbox v-model="lovingVue"></base-checkbox>

Tags: Front-end Vue.js

Posted on Sat, 18 Sep 2021 23:42:17 -0400 by turboprop