Shiladitya Bose
Shiladitya Bose

Reputation: 1183

How to 2-way bind props with local data of a component in Vue 3?

Can anyone tell me how I can bind the prop of a component to a data property of its own? For example, consider I have a component called ModalComponent

<template>  // ModalComponent.vue
   <div v-if="showModal">
      ...
      <button @click="showModal = !showModal">close the modal internally</button>
   </div>
</template>

<script>
export default {
  props: {
    show: {
      type: Boolean,
      default: false
    },
  },
  data() {
    return {
      showModal: false,
    }
  }
}
</script>

<style>
</style>

Now consider I am using this modal as a reusable component from inside a parent component using an external button to open up the pop up for the modal.

<template>
  <button @click="showChild = !showChild">click to open modal</button>
  <ModalComponent :show="showChild" />
</template>

<script>
export default {
  components: {ModalComponent},
  data() {
    return {
      showChild: false,    
    }
  }
}
</script>

<style>
</style>

How do I make it so that every time the parent clicks on the button, the modal pops up by binding the local showModal to the prop show ? And when the modal is closed internally by the local close button, if I click on the parent button again it will re-pop up? (I am using Vue 3, just in case)

Any help would be appreciated. Thanks.

Upvotes: 0

Views: 3538

Answers (1)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

The perfect solution for this case is using v-model instead of passing a prop :

in child component define modelValue as prop and emit its value to the parent using $emit function:

<template>  // ModalComponent.vue
   <div v-if="modelValue">
      ...
      <button @click="$emit('update:modelValue',!modelValue)">close the modal internally</button>
   </div>
</template>

<script>
export default {
  props: {
    modelValue: {
      type: Boolean,
      default: false
    },
  },
  emits: ['update:modelValue'],

}
</script>

in parent component just use v-model to bind the value :

<template>
  <button @click="showChild = !showChild">click to open modal</button>
  <ModalComponent v-model="showChild" />
</template>

<script>
export default {
  components: {ModalComponent},
  data() {
    return {
      showChild: false,    
    }
  }
}
</script>

Upvotes: 5

Related Questions