How do you emit an event from a nuxt plugin?

前端 未结 3 1926
傲寒
傲寒 2021-01-18 19:19

I am creating a plugin that will emit basic nuxt events triggered by sockets. The nuxt event will then be recieved and open a snackbar. When inside a component it is easy to

相关标签:
3条回答
  • 2021-01-18 19:28

    I figured another way to do it, by creating a manual event bus using Vue itself and using combined inject

    In my case, I had a global axios interceptor to check the responses for a status code of 401, meaning that the user's session has expired and then display a notification to them.

    
    // my-plugin.js
    import Vue from 'vue'
    
    export default function ({ $axios, app }, inject){
    
      inject('eventHub', new Vue()); // this is the same as Vue.prototype.$eventHub = new Vue()
    
      // checking for status 
        $axios.onError((error) => {
        const code = parseInt(error.response && error.response.status)
        if (code === 401) {
          app.$auth.logout() // logout if errors have happened
          app.$eventHub.$emit('session-expired')
        }
      })
    }
    
    

    The event bus is now accessible both in context and in any Vue instance

    // login.vue
    
    export default{
      data(){
        // data
      },
      created(){
        this.$eventHub.$once('session-expired', ()=> {
        this.showAlert()
      })
      },
      methods: {
        showAlert(){
          // display notifcations
        }
      }
    }
    
    0 讨论(0)
  • 2021-01-18 19:29

    You can use something like this in your plugin.js file, what the plugin will do is use window.$nuxt.$emit which is available on the client side

    export default function (context) {
        $nuxt.$emit('event-to-emit')
    }
    
    0 讨论(0)
  • 2021-01-18 19:49

    It's not the solution I was looking for, but as a workaround I injected another instance of vue as a plugin to use as an event bus. It doesn't use the nuxt context as I initially wanted, but it works.

    import Vue from 'vue'
    
    export const bus = new Vue()
    
    export default (_context, inject) => {
    
        // Client only
        if (process.client) {
            // Event bus for plugins
            inject('bus', bus)
        }
    }
    
    
    /**
     * Socket that pops open a snackbar
     */
    export default ({ app: { $bus, $sockets } }) => {
    
        // Incoming message
        $sockets.on('message', payload => {
    
            // When we are on the messages page with the user
            if (window.location.pathname === `/messages/${payload.message.sender.username}`) {
                $bus.$emit('message-conversation', payload)
            }
            // Elsewhere, or messages with a different user
            else {
                $bus.$emit('open-snackbar', {
                    body: payload.message.body,
                    link: `/messages/${payload.message.sender.username}`,
                    user: payload.message.sender
                })
            }
        })
    
        // Incoming notification
        $sockets.on('notification', payload => {
            $bus.$emit('open-snackbar', {
                body: payload.notification.text,
                link: payload.notification.link || '/notifications',
                user: payload.notification.source
            })
        })
    }
    
    
    0 讨论(0)
提交回复
热议问题