VueJS - VueX 和 flash 消息
VueJS - VueX and flash messages
我使用 VueJS 2、VueX、NuxtJS 和 Vue -Snotify (artemsky/vue-snotify) 用于 flash 通知。
这可能不是 VueX 的正确使用,但我想 dispatch 在 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 的实例?
不好
我意识到 app 实例是在 Vue 存储的初始化中注入的。因此,您可以通过 this.app.$snotify
访问所需的 Snotify 服务。
此外,store 的另一个地方接收 Nuxt 上下文作为 第二个参数 是 nuxtServerInit
[2]。因此,您可以使用类似下一个 snippet.
的方式 access 访问 service
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 消息 的形式显示在其他组件中在这种特殊情况下使用 Snotify。因此,总结一下我对声明的赞赏,我认为操作仅负责将 store 的 state 更改为 definition 的唯一真实来源。
您必须使用 突变 并仅存储 对象 。然后,在您的视图或 HOC(高阶组件)中,使用可用的 Snotify 设置表示逻辑。为了支持我的回答,我强烈推荐 this library 因为它有更好的 API 与 Vuex 而且它有一个很好的展示界面 (UI/UX)。免责声明:我并不是说这个比 Snotify 好,每一个都是为了满足略有不同的目的而构建的,至少就用户体验概念而言是这样。两者都很棒,可以用任何一种方式来说明这个用例。
我将更改您的第二个代码段:
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 页面有一个 different生命周期,直到我也看到这个 example and realize that Nuxt still been Vue on the background. Thus, any page actually is also a component by 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
我使用 VueJS 2、VueX、NuxtJS 和 Vue -Snotify (artemsky/vue-snotify) 用于 flash 通知。
这可能不是 VueX 的正确使用,但我想 dispatch 在 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 的实例?
不好
我意识到 app 实例是在 Vue 存储的初始化中注入的。因此,您可以通过 this.app.$snotify
访问所需的 Snotify 服务。
此外,store 的另一个地方接收 Nuxt 上下文作为 第二个参数 是 nuxtServerInit
[2]。因此,您可以使用类似下一个 snippet.
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 消息 的形式显示在其他组件中在这种特殊情况下使用 Snotify。因此,总结一下我对声明的赞赏,我认为操作仅负责将 store 的 state 更改为 definition 的唯一真实来源。
您必须使用 突变 并仅存储 对象 。然后,在您的视图或 HOC(高阶组件)中,使用可用的 Snotify 设置表示逻辑。为了支持我的回答,我强烈推荐 this library 因为它有更好的 API 与 Vuex 而且它有一个很好的展示界面 (UI/UX)。免责声明:我并不是说这个比 Snotify 好,每一个都是为了满足略有不同的目的而构建的,至少就用户体验概念而言是这样。两者都很棒,可以用任何一种方式来说明这个用例。
我将更改您的第二个代码段:
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 页面有一个 different生命周期,直到我也看到这个 example and realize that Nuxt still been Vue on the background. Thus, any page actually is also a component by 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