2

I have a modal in one of my pages and I want to add a class “active” on body when I open the modal, so I can make the body overflow hidden (no scroll). Is there a way to toogle a class on the body tag when I click from one component? I can't figure it out...

I use routes

<template>
    <div id="app">
        <Header />
        <router-view/>
        <Footer />
    </div>
</template>

Thx in advance

Luna84
  • 147
  • 2
  • 15

2 Answers2

3

The correct way of doing this in Vue is to communicate between components, in this case it might not be a simple parent/child communication, so you might want to create an Event Bus.

By using this approach the modal's code is has minimum effects on the rest of your application, it only dispatches events that you can subscribe to from any other component.

Note: In this case you won't add the class on your body tag (because you can't mount Vue on body), but you may just add it to your root div to have a similar result.

const eventBus = new Vue();

Vue.component('modal', {
  props: ['isOpen'],
  template: `
   <div class="modal" v-if="isOpen">This is a modal</div>
  `,
});

Vue.component('wrapper', {
  template: `
    <div>
      <modal :isOpen="isModalOpen"></modal>
      <button @click="toggleModal">toggle modal</button>
    </div>
  `,
  data() {
    return {
      isModalOpen: false,
    }
  },
  methods: {
    toggleModal() {
      this.isModalOpen = !this.isModalOpen;
      eventBus.$emit('toggleModal', this.isModalOpen);
    }
  }
});

new Vue({
  el: "#app",
  data: {
    active: false,
  },
  created() {
    eventBus.$on('toggleModal', (isModalOpen) => {
      this.active = isModalOpen;
    });
  },
})
.active {
  background: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app" :class="{active}">
  <wrapper></wrapper>
</div>
Amr Noman
  • 2,597
  • 13
  • 24
2

This should help

document.body.className += 'active'

Gagan
  • 5,416
  • 13
  • 58
  • 86