hendy0817
hendy0817

Reputation: 1079

Vue / Nuxt access function from global component

I have a globally registered component (modal) in my NUXT app default layout which I would like to be able to trigger a method from any other component on a click event. I had it initially setup by importing the component into each page but I would rather this be a global component and not have to import explicitly on each page and just have one register call in the default layout. Is this achievable my using $root.$emit? or should I look into a vue store?

Default Layout:

<template>
  <div class="layout-wrapper">

    <Nuxt />

    <Modal />

  </div>
</template>

    <script>
    import Modal from "~/components/Modal.vue";
    
    export default {
      name: "DefaultLayout",
      components: {
       Modal
      }
    };
    </script>

Modal:

<template>
  <div>
    <el-dialog :visible.sync="modal">
      <div class="dialog-content">
        <p>
         Modal Content
        </p>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { Dialog } from "element-ui";

export default {
  name: "Modal",
  components: {
    "el-dialog": Dialog
  },
  data() {
    return {
      modalOne: false
    };
  },
  methods: {
    openModal() {
      this.modalOne = true;
    }
  }
};
</script>

other component to call method from:

 <a href="javascript:void(0)" @click="openModal">Open</a>

Upvotes: 0

Views: 1591

Answers (1)

Nicolas Pennec
Nicolas Pennec

Reputation: 7631

Using a store is a a good solution for your need:

1/ create a store file store/index.js

export const state = () => ({
  modal: false
});

export const mutations = {
  SET_MODAL (state, value) {
    state.modal = value
  }
};

2/ update your layout to set store data to the modal component:

<template>
  <div class="layout-wrapper">
    <Nuxt />
    <Modal open="$store.state.modal" />
  </div>
</template>

3/ update your component to read the open value:

<template>
  <div>
    <el-dialog :visible.sync="open">
      <div class="dialog-content">
        <p>
         Modal Content
        </p>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { Dialog } from "element-ui";

export default {
  props: {
    open: Boolean // see https://v2.vuejs.org/v2/guide/components-props.html
  },
  name: "Modal",
  components: {
    "el-dialog": Dialog
  }
};
</script>

4/ toggle the store value from a nuxt page (see https://nuxtjs.org/docs/2.x/directory-structure/store)

<script>
export default {
  methods: {
    openModal (e) {
      this.$store.commit('SET_MODAL', true);
    }
  },
  ...
}
</script>

Upvotes: 1

Related Questions