【问题标题】:VueJS - VueX and flash messagesVueJS - VueX 和 flash 消息
【发布时间】:2018-10-17 07:35:39
【问题描述】:

我使用 VueJS 2VueXNuxtJSVue-Snotify (artemsky/vue-snotify) 进行闪存通知。

这可能不是正确使用 VueX,但我想调度在 try/catch 中捕获的错误。

try {
    throw new Error('test')
} catch (error) {
    this.$store.dispatch('errorHandler', error)
}

如果出现多个错误,则使用 VueX 的调度应该使用带有循环的 Snotify-View 显示通知。

actions: {
    async errorHandler (error) {
        this.$snotify.error(error)
        // and if multiple errors, then while on error
    }
}

你怎么看,如何在 VueX 中恢复 $snotify 的实例?

【问题讨论】:

  • 如果代码不会影响 vuex 状态,我不会使用 vuex 操作。
  • 好的,我明白了......但是我怎样才能让一个组件来识别所有错误呢?
  • 将错误添加到错误堆栈(在 Vuex 中),在页面上有一个与错误堆栈交互并使用 $snotify 显示它们的组件。也感谢你今天早上用那个图书馆的名字打喷嚏:)
  • 感谢@Bert,但我如何从 VueX 获取错误堆栈?使用 setTimeout()? :)
  • 你可以从 Vuex 获取它,就像你从 Vuex 获取任何东西一样;使用吸气剂。当堆栈更改时,您的组件可能会监视调用 snotify。

标签: vue.js vuex nuxt.js


【解决方案1】:

不好

我意识到 app 实例是在 Vue 存储的初始化中注入的。因此,您可以通过this.app.$snotify 访问您想要的Snotify 服务。

此外,store 中另一个接收 Nuxt 上下文作为第二个参数 的地方是nuxtServerInit[2]。因此,您可以使用类似下一个 sn-p 的方式访问 服务

actions: {
    nuxtServerInit ({ state }, { app }) {
        // Workaround
        state.Snotify = app.$snotify // inject the context in the store
    },
    // Then, you can called as you want
    // There is not necessity to prefix the method with async keyword
    errorHandler ({ state }, message) {
        state.Snotify.error(message)
    }
}

在我看来,store 没有任何责任来处理数据的呈现行为。因此,在这种情况下,store 的唯一目标是将要在其他组件中显示的消息传递为 flash message,并使用 Snotify 在这种特殊情况下。因此,总结一下我对声明的欣赏,我认为行动只负责将 商店状态 更改为 唯一的事实来源definition

您必须改为使用 mutation 并仅存储 Object。然后,在您的视图中或 HOC(高阶组件)使用 Snotify 在可用的地方设置表示逻辑。为了支持我的回答,我强烈推荐 this library,因为它有更好的 API 可以与 Vuex 进行通信,而且它的演示效果也很好界面(UI/UX)。免责声明:我并不是说这个比 Snotify 更好,每个都是为了满足稍微不同的目的,至少就用户体验概念而言。两者都很棒,可以用任何一种方式来说明这个用例。


我会将您的第二个 sn-p 更改为:

state: {
    flash: null
}
mutations: {
    // Just extract message from the context that you are set before
    SET_ERROR (state, { message, title = 'Something happens!' }) {
        state.flash = { 
            type: 'error',
            title, 
            message
        }
    },
    FLUSH_FLASH (state) {
        state.flash = null
    }
}

另外,我将把它添加到一些视图/布局/组件/HOC(我使用 SFC 方式作为其最常见的用途)

<template>
    <vue-snotify />
    ...
</template>

<script>
   export default {
       // I use fetch because this is the lifecycle hook that executes 
       // immediately before page render is sure. And its purpose is to fill
       // the store before page render. But, to the best of my knowledge, 
       // this is the only place that you could use to trigger an immediately
       // executed function at the beginning of page render. However, also
       // you could use a middleware instead or "preferably use a wrapper 
       // component and get leverage of component lifecycle and use `mounted`" [4]
       fetch({ app, store }) {
           if (store.state.flash) {
               const { type, title, message: body } = store.state.flash
               const toast = app.$snotify[type](body, title)

               toast.on('destroyed', (t) => { store.commit('FLUSH_FLASH') })
           }
       },
       data: () => ({
           ...
       })
</script>

也许,上面的代码对您来说功能并不完整,但我建议您应该测试类似的方法并满足您的需求。

编辑

我想根据我上次与组件生命周期相关的更新指出我的答案的另一个改进。一开始,我实际上想将消息放在组件 mounted 方法中,但后来我认为 Nuxt 页面有一个 不同 生命周期,直到我看到这个 example并意识到 Nuxt 仍然是 Vue 在后台。因此,任何页面实际上也是definition组件。然后你也可以做一个语义化的方法。

<template>
    <vue-snotify />
    ...
</template>

<script>
   export default {
       data: () => ({
           ...
       }),
       // Show the flash at the beginning when it's necessary
       mounted: {
           if (this.notification) {
               const { type, title, message: body } = this.notification
               const toast = this.$snotify[type](body, title)

               toast.on('destroyed', (t) => { this.$store.commit('FLUSH_FLASH') })
           }
       },
       computed: {
           notification () {
               return this.$store.state.flush
           }
       }
</script>

参考文献

[1]https://zendev.com/2018/06/07/async-data-options-in-vue-nuxt.html

[2]https://twitter.com/krutiepatel/status/1000022559184764930

[3]https://github.com/artemsky/vue-snotify/blob/master/example/src/App/app.ts

[4]https://medium.com/@fishpercolator/implementing-a-global-snackbar-in-nuxt-js-vuetify-using-vuex-a92b78e5651b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 2017-10-30
    • 2015-09-06
    相关资源
    最近更新 更多