【问题标题】:How do you emit an event from a nuxt plugin?如何从 nuxt 插件发出事件?
【发布时间】:2019-09-28 00:51:58
【问题描述】:

我正在创建一个插件,它将发出由套接字触发的基本 nuxt 事件。然后将收到 nuxt 事件并打开一个小吃店。在组件内部时,使用$nuxt 可以轻松发送和接收事件

this.$nuxt.$on('open-snackbar', this.handler)
this.$nuxt.$emit('open-snackbar', options)

但是我如何尝试在插件中执行此操作,因此它不绑定到任何一个页面,而是存在于整个应用程序中。我似乎无法弄清楚如何从所述插件中发出它:

export default (context) => {
    console.log(context)
    console.log(context.$emit)
    console.log(context.emit)
    console.log(context.$nuxt)
    console.log(context.app.emit)
    console.log(context.app.$nuxt)
}

context.app 似乎是正确的对象,但它似乎不起作用。有什么想法吗?

【问题讨论】:

    标签: nuxt.js


    【解决方案1】:

    你可以在你的 plugin.js 文件中使用类似的东西,插件会使用window.$nuxt.$emit,它在客户端可用

    export default function (context) {
        $nuxt.$emit('event-to-emit')
    }
    

    【讨论】:

    • 我的 nuxt.config.js 中有 ..., target: 'static', ssr: false
    【解决方案2】:

    我想出了另一种方法,即使用 Vue 本身创建手动事件总线并使用 combined inject

    在我的例子中,我有一个全局 axios 拦截器来检查状态代码 401 的响应,这意味着用户的会话已过期,然后向他们显示通知。

    
    // 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')
        }
      })
    }
    
    

    现在可以在上下文和任何 Vue 实例中访问事件总线

    // login.vue
    
    export default{
      data(){
        // data
      },
      created(){
        this.$eventHub.$once('session-expired', ()=> {
        this.showAlert()
      })
      },
      methods: {
        showAlert(){
          // display notifcations
        }
      }
    }
    

    【讨论】:

    • 看上面的答案,他们恰好有相同的解决方案。
    【解决方案3】:

    这不是我正在寻找的解决方案,但作为一种解决方法,我注入了另一个 vue 实例作为插件用作事件总线。它没有像我最初想要的那样使用 nuxt 上下文,但它可以工作。

    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
            })
        })
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-12
      • 2018-06-06
      • 2018-10-21
      • 2021-01-14
      • 2016-03-30
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      相关资源
      最近更新 更多