SoFunction
Updated on 2025-04-09

How to customize the v-model of a component in vue2

How to customize the v-model of a component

During work, there are often problems involving parent-child component data updates and page corresponding data style changes.

In layman's terms, it is that what involves common components can be extracted as child components. If the data related to the child component in the parent component changes, the data in the child component will also change. If the data of the child component changes, a certain amount of processing is required to change the relevant data in the parent component.

How to handle: Consider using the v-model of custom components (in vue2)

Parent component

<search-tab :list="list" v-model="active" />
...
export default {
    data(){
        return {
            list: [],
            active: 0
        }
    }
}
...

Subcomponent SearchTab

<el-tabs :value="active" @tab-click="handleClick">
  <el-tab-pane v-for="(item, key) in list" :key="key" :label="" :name=""></el-tab-pane>
</el-tabs>
...
export default {
  name: 'SearchTab',
  props: {
    active: {
      type: Number,
      default: 0
    },
    list: Array
  },
  model: {
    prop: 'active',
    event: 'changeActive'
  },
  methods: {
    handleClick(val) {
      this.$emit('changeActive', )
    }
  }
}
...

This method can be responsive if it involves the selected style of the selected component

If we do not use the v-model method of the component to customize the component, but instead communicate with ordinary parent-child components, the child component changes the value of the parent component through another declared in the child component as an intermediate variable, and listens to the value of the intermediate variable to change the value in the parent component. Although this method can change the value, the selected style cannot be updated in time.

Subcomponent example

<el-tabs :value="active" @tab-click="handleClick">
  <el-tab-pane v-for="(item, key) in list" :key="key" :label="" :name=""></el-tab-pane>
</el-tabs>
...
export default {
  name: 'SearchTab',
  props: {
    name: String,
    activeTab: {
      type: String,
      default: '0'
    },
    list: Array
  },
  data() {
    return {
      active: 
    }
  },
  watch: {
    active() {
       = 
    }
  },
  methods: {
    handleClick(val) {
      (val)
    }
  }
}
...

The difference between vue2 and vue3 in custom component v-model

In vue development, a custom component is usually encapsulated and the v-model bidirectional binding function is implemented.

In vue2, this is usually implemented

Parent component

<template>
  <Child v-model="number"></Child>    
</template>
<script>
  export default {
    data() {
      return {
        number: 0
      }
    },
    components: {
      Child: () => import("./")
    }
  }
</script>

Subcomponents

<template>
  <button @click="handleClick">{{ value }}</button>
</template>
&lt;script&gt;
  export default {
    props: {
      value: Number
    },
    methods: {
      handleClick() {
        // Go out by emit an input event to implement v-model        this.$emit('input',  + 1)
      }
    }
  }
&lt;/script&gt;

In vue3, this is achieved

Parent component

<template>
  <Child v-model="number"></Child>    
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
  setup() {
    const number = ref(0);
    return {
      number
    };
  },
});
</script>

Subcomponents

<template>
  <button @click="handleClick">{{ value }}</button>
</template>
&lt;script lang="ts"&gt;
import { defineComponent } from 'vue';
export default defineComponent({
  props: {
    // Replaced with modelValue    modelValue: Number
  },
  setup(props, { emit }) {
    // Close the pop-up layer    const handleClick = () =&gt; emit('update:modelValue',  + 1);
    return { handleClick };
  },
});
&lt;/script&gt;

The above is personal experience. I hope you can give you a reference and I hope you can support me more.