mart cube
mart cube

Reputation: 665

Vue modal component using in parent component

I'm building simple modal component with Vue. I want to use this component in a parent components and to be able to toggle it from the parent.

This is my code now of the modal component:

<script>
export default {
	name: 'Modal',
	data() {
		return {
			modalOpen: true,
		}
	},
	methods: {
		modalToggle() {
			this.modalOpen = !this.modalOpen
		},
	},
}
</script>
<template>
	<div v-if="modalOpen" class="modal">
		<div class="body">
			body
		</div>
		<div class="btn_cancel" @click="modalToggle">
			<i class="icon icon-cancel" />
		</div>
	</div>
</template>

I use the v-if to toggle the rendering and it works with the button i created inside my modal component.

However my problem is: I don't know how to toggle it with simple button from parent component. I don't know how to access the modalOpen data from the modal component

Upvotes: 1

Views: 2943

Answers (3)

Emīls Gulbis
Emīls Gulbis

Reputation: 2070

With your current implementation I would suggest you to use refs https://v2.vuejs.org/v2/guide/components-edge-cases.html#Accessing-Child-Component-Instances-amp-Child-Elements

So in your parent component add ref="child" to modal (child) component and then open your modal by calling this.$refs.child.modalToggle()

Upvotes: 1

N1Creator
N1Creator

Reputation: 339

Ok, let's try to do it right. I propose to make a full-fledged component and control the opening and closing of a modal window using the v-model in parent components or in other includes.

1) We need declare prop - "value" in "props" for child component.

<script>
export default {
    name: 'Modal',
    props: ["value"],
    data() {
        return {
            modalOpen: true,
        }
    },
    methods: {
        modalToggle() {
            this.modalOpen = !this.modalOpen
        },
    },
}
</script>

2) Replace your "modalToggle" that:

modalToggle() {
  this.$emit('input', !this.value);
}

3) In parent components or other includes declare "modal=false" var and use on component v-model="modal" and any control buttons for modal var.

summary

<template>
    <div v-if="value" class="modal">
        <div class="body">
            body
        </div>
        <div class="btn_cancel" @click="modalToggle">
            <i class="icon icon-cancel" />
        </div>
    </div>
</template>

<script>
export default {
  name: "Modal",
  props: ["value"],
  methods: {
    modalToggle() {
      this.$emit("input", !this.value);
    }
  }
};
</script>

Example:

Vue.component('modal', {
  template: '<div v-if="value" class="modal"><div class="body">modal body</div><div class="btn_cancel" @click="modalToggle">close modal<i class="icon icon-cancel" /></div></div>',
  props: ["value"],
	methods: {
		modalToggle() {
      this.$emit('input', !this.value);
		}
	}
});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app',
  data:() =>({
  modal: false
  }),
  methods: {
  openModal() {
  this.modal = !this.modal;
  }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div @click="openModal">Btn modal</div>
  
  <modal v-model="modal"></modal>
</div>

Upvotes: 2

sureshvv
sureshvv

Reputation: 4422

  1. You can use an "activator" slot

  2. You can use ref="xxx" on the child and access it from the parent

Upvotes: 0

Related Questions