Vue2.0 Utilizes v model to Realize props Bidirectional Binding of Components

  • 2021-08-03 09:07:48
  • OfStack

I started to use vue2 to build the project in the project. One big difference with vue1 is that 2 cancels the bidirectional binding of props and changes it to a one-way data flow that can only be transmitted from the parent to the child. The original intention is of course good, in order to avoid the data confusion easily caused by bidirectional binding in the project.

Solution 1

Then I started to refer to the online and github solutions and so on, and found that many solutions are like this

Create a copy of the props attribute with the data object The watch props attribute assigns the data copy to synchronize modifications to props outside the component watch data copy, emit1 function notifications outside the component

Here, take the most common modal as an example: modal is quite suitable for bidirectional binding, and the external can control the display or hiding of components, while the internal closing of components can control the hiding of visible attributes, and the visible attributes are transmitted to the external synchronously


///modal.vue  Component 
<template>
 <div class="modal" v-show="visible">
  <div class="close" @click="cancel">X</div>
 </div>
</template>

<script>
export default {
 name:'modal',
 props: {
  value: {
  type: Boolean,
  default:false
  }
 },

 data () {
 return {
  visible:false
 }
 },
 watch:{
  value(val) {
  console.log(val);
  this.visible = val;
  },
  visible(val) {
  this.$emit("visible-change",val);
  }
 },
 methods:{
 cancel(){
  this.visible = false;
 }
 },
 mounted() {
 if (this.value) {
  this.visible = true;
 }
 }
}
</script>


/// Call modal Component 
<modal :value="isShow" @visible-change="modalVisibleChange"></modal>

export default {
 name: 'app',
 data () {
 return {
  isShow:true,
 }
 },
 methods:{
  modalVisibleChange(val){
  this.isShow = val;
  }
 }
}

This solves the problem of bi-directional binding of components props. However, there is a phenomenon that is not very beautiful, that is, when the parent calls the modal component, it needs to write an methods of modalVisibleChange. It always seems that this part of the code is redundant. In particular, writing a common component for others to use is too troublesome to call. Can you realize the bidirectional binding of props without writing method? The answer is yes.

Beautiful solution

That is, using v-model, a hidden input control is placed inside the component to save the value of v-model for bidirectional binding

Change it to the following code:


<template>
 <div class="modal" v-show="visible">
  <div class="close" @click="cancel">X</div>
  <input type="text" :value="value" style='display:none;'>
 </div>
</template>

<script>
export default {
 props: {
  value: {
  type: Boolean,
  default:false
  }
 },

 data () {
 return {
  visible:false
 }
 },
 watch:{
  value(val) {
  console.log(val);
  this.visible = val;
  },
  visible(val) {
  this.$emit('input', val);
  }
 },
 methods:{
 cancel(){
  this.visible = false;
 }
 },
 mounted() {
 if (this.value) {
  this.visible = true;
 }
 }
}
</script>


/// Call modal Component 

 <modal v-model="isShow"></modal>

export default {
 name: 'app',
 data () {
 return {
  isShow:false
 }
 }
}
</script>

In this way, the code for calling components is not very simple. If other personnel want to call, it will be very easy. As long as isShow is set, the display or hiding of modal components can be controlled. At the same time, if the internal close button of modal components is closed, the status will be transmitted to isShow.


Related articles: