如何使用 Nuxt、Vuetify 和 Vuex 创建全局 Snackbar。
太长不看
引言
Snackbar(也称为提示框或 Toast)几乎存在于所有应用程序中。它们便于在用户交互后显示重要信息。如果您使用的是Vuetify的 Snackbar 组件,您可能已经注意到,它没有全局对象来调用函数并显示 Snackbar 组件。我曾短暂使用过Quasarthis.$q.notify('Message') ,并深深爱上了它,因此我尝试使用 Vuetify 和 Vuex 来复现类似的功能,并在此分享我的实现方法。本教程将使用Nuxt ,但您也可以将代码适配到原生 Vue 应用中(感谢 David 展示了如何在不使用 Nuxt 的情况下实现 Snackbar:https://dev.to/dzvid/comment/17nip)。
店铺
首先,我们需要为我们的 Snackbar 创建一个 store 模块。如果您不了解 Vuex,可以将 store 理解为一个用于存储变量的全局仓库。有关 Nuxt 和 Vuex 的更多信息,请点击此处。
// ~/store/snackbar.js
export const state = () => ({
content: '',
color: ''
})
export const mutations = {
showMessage (state, payload) {
state.content = payload.content
state.color = payload.color
}
}
我们的商店将包含content各州color的信息。这些数据将用于填充我们的小吃吧组件。
直接修改状态数据并非好做法,因此我们创建了一个名为 `mutation` 的 mutation showMessage。它会改变状态值,使监听状态变化更加容易。
插件
为了让通知功能在整个应用程序中可用,我们需要创建一个插件。我们可以跳过创建插件的步骤,直接在组件中使用,但this.$store.commit(...)创建插件更清晰易读,并且避免了将变更映射到多个组件。mapMutation(...)this.$notifier.showMessage(...)
// ~/plugins/notifier.js
export default ({ app, store }, inject) => {
inject('notifier', {
showMessage ({ content = '', color = '' }) {
store.commit('snackbar/showMessage', { content, color })
}
})
}
这段代码会$notifier在我们的组件中注入一个对象。该对象包含一个showMessage函数,用于接收参数content并color提交showMessage对 Snackbar 存储的变更。有关 Nuxt 插件的更多信息,请点击此处查看。
我们还需要注册该插件。nuxt.config.js
export default {
...
plugins: [
'~/plugins/notifier.js'
],
...
}
零食吧组件
我们的提示栏组件很简单,它负责在屏幕上显示消息。
// ~/components/Snackbar.vue
<template>
<v-snackbar v-model="show" :color="color">
{{ message }}
<v-btn text @click="show = false">Close</v-btn>
</v-snackbar>
</template>
<script>
export default {
data () {
return {
show: false,
message: '',
color: ''
}
},
created () {
this.$store.subscribe((mutation, state) => {
if (mutation.type === 'snackbar/showMessage') {
this.message = state.snackbar.content
this.color = state.snackbar.color
this.show = true
}
})
}
}
</script>
组件创建后便开始监听变更事件。它会设置 Snackbar 信息,并showMessage在 Snackbar 存储中的变更事件被调用时显示该信息。
布局
我们需要在应用程序中添加小吃吧功能:
// ~/layouts/default.vue
<template>
<v-app>
...
<Snackbar></Snackbar>
...
</v-app>
</template>
<script>
import Snackbar from '~/components/Snackbar.vue'
export default {
components: { Snackbar },
...
}
</script>
小吃店
最后,我们将创建一个按钮来显示我们的零食吧正在运行:
// ~/pages/index.vue
<template>
...
<v-btn color="primary" @click="showSnackbar">
Show snackbar
</v-btn>
...
</template>
<script>
export default {
...
methods: {
showSnackbar () {
this.$notifier.showMessage({ content: 'Hello, snackbar', color: 'info' })
}
}
...
}
</script>
结论
就是这样。很简单。以后无论在哪里都可以调用,this.$notifier.showMessage(...)无需为每种情况都创建一个 Snackbar。接下来,你可以让它同时显示多个 Snackbar,并在关闭按钮之外为 Snackbar 添加自定义操作。好了,就这些了。如果你找到了更好的解决方案,请随时留言。