我使用 VueJS 2 , VueX , NuxtJS 和 Vue-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的实例?
答案 0 :(得分:3)
我意识到 app 实例是在 Vue 商店的初始化中注入的。因此,您可以通过this.app.$snotify
访问所需的 Snotify 服务。
另外,商店中另一个接收 Nuxt 上下文作为第二个参数的地方是nuxtServerInit
[2] 。因此,您可以使用下一个片段之类的东西访问到服务。
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)
}
}
在我看来,商店没有任何责任来处理数据的表示行为。因此,在这种情况下,商店的唯一目标是在要显示的组件之间传递消息,以即时消息的形式通过 Snotify < / strong>。因此,总结一下我对声明的赞赏,我认为行动仅是将商店的状态更改为唯一事实来源的责任,由definition。
您必须改用变异并仅存储 Object 。然后,在您的视图或 HOC (高阶组件)中,使用 Snotify (如果可用)设置演示逻辑。为了支持我的回答,我强烈建议this 库,因为它具有更好的 API 与 Vuex 进行通信,并且具有良好的演示界面(UI / UX)。免责声明:我并不是说这比 Snotify 更好,每一个都旨在满足至少在UX概念方面稍有不同的目的。两者都很棒,可以用任何一种方式来说明此用例。
我将为您更改第二个片段:
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
}
}
而且,我将其添加到某些view / layout / component / 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 页面的生命周期不同,直到看到{ {3}},并且意识到 Nuxt 在背景上仍然是 Vue 。因此,example实际上,任何页面也是组件。然后,您也可以执行很多语义方法。
<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] definition
[2] https://zendev.com/2018/06/07/async-data-options-in-vue-nuxt.html
[3] https://twitter.com/krutiepatel/status/1000022559184764930
[4] https://github.com/artemsky/vue-snotify/blob/master/example/src/App/app.ts