Search code examples
javascriptvue.jsnuxt.jsdom-events

How to listen for a page $emit in a nuxt layout?


Nuxt 2.15.6; I want to switch the layout of my menu component by dynamically switching menu components in my root layout.

default.vue

<template>
  <component :is="navLayout"></component>
  <Nuxt :navLayout="navLayout = $event" />
</template>
data() {
  return {
    navLayout: "default"
  };
},

In the "child" components of , my pages eg. login.vue (/login) I $emit an event;

...
import nav2 from "@/layouts/nav2";
...
created() {
  this.$emit("navLayout", nav2);
},

Now it seems to be the <Nuxt> component is not able to catch the event. I also tried calling a <Nuxt @navLayout="test()" /> method.

How can I avoid this.$root.$emit(...); in my login.vue and

this.$root.$on("navLayout", navLayout => {
  this.navLayout = navLayout;
});

in default.vue?


Solution

  • EDIT: This answer works fine as it looks like you cannot do it right now: https://github.com/nuxt/nuxt.js/issues/8122#issuecomment-709443008

    In the child component

    <button @click="$nuxt.$emit('eventName', 'nice payload')">nice</button>
    

    On the default layout

    <script>
    export default {
      created() {
        this.$nuxt.$on('eventName', ($event) => this.test($event))
      },
      methods: {
        test(e) {
          console.log('test ok >>', e)
        },
      },
    }
    </script>
    

    Putting a listener on Nuxt itself does not work.

    <Nuxt @navLayout="navLayout = $event" :navLayout="navLayout" />
    

    I can see the event go and the listener plugged to <nuxt></nuxt> but it does not trigger any method with the listener...

    PS: works for <nuxt-child></nuxt-child> at least.