There is no way to create a global notification system. With the ability to send a notification from anywhere in the application.
You could use a storage module. Implement in it a queue of notifications. And in this case, you need to delete the notification from storage after the snackbar is hidden (after the animation)
@cawa-93 how about using a snackbar (or anything similar) which has a computed variable based on vuex like this:
YourNotification.vue
export default {
computed:{
notification(){
return this.$store.state.globalNotifications
}
}
}
Place this component anywhere in your layout only once.. then all you need to do is pushing into the vuex store any globalNotification. Would this help?
I don't see the point of implementing someting on the side of vuetify.. thats a perfect usecase for the global state management vuex in my opinion.
Yes, I'm talking about this. But I need to somehow track the moment when the bar was closed to remove it from the store. If you display several snackbars, they overlap each other. Therefore, it is important to handle the event when one bar is completely hidden to display the next one. Rotation of notifications Example:
<template>
<div>
<v-snackbar
v-model="show"
@close="removeFromStore"
>{{ notification.text }}
<v-btn flat class="pink--text" @click.native="show = false">Close</v-btn>
</v-snackbar>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
computed: {
notification(){
return this.$store.state.globalNotifications[0]
}
},
mounted() {
if (this.notification) {
this.show = true
}
},
methods: {
removeFromStore() {
this.$store.dispatch('shiftNotification')
if (this.notification) {
this.show = true
}
}
}
}
</script>
I represent this order of work:
this.show
set to true
this.show
set to false
close
@cawa-93 can't you watch the show variable:
watch:{
show(value){
if(value === false){
this.removeFromStore()
}
}
}
maybe a short timeout might be necessary.. but I haven't tested it. Just been curious
The fact is that the parameter show
changes BEFORE the bar completely disappears. As a result, a new notification appears instantly. I want to run the removeFromStore
method only after the current bar disappears completely (the animation of the disappearance is completed).
It also leads to the second problem: the timeout is not reset.
maybe this helps: https://codepen.io/anon/pen/bRexNR?editors=1011
I simply show the snackbar as long there are items available (setting timeout to false). Is that a solution?
Nope. This is not what I want to get
And delaying the next snackbar like dohomi suggested is not a solution either?
@nekosaur Yes This is the solution. But as for me, this is a very rough workaround. In reality, the delay before the new notification is displayed is not related to the previous one. Because of which they can potentially overlap.
Not to mention the reassigned code. It would be much easier to have a special event that would shoot immediately after the end of animation and reset timeout
It's strange that the problem has not been solved yet.
In fact, in the current version Snackbar can be used in the simplest case. But very often, when a single notification is displayed, you will likely need to display a few more in a short time.
I think Quasar has a great solution http://quasar-framework.org/components/notify.html. It would be healthy to do something like this and in Vuetify
I'm using the Vuetify, and unfortunately the Snackbar component is not suitable for me. Is it planned to fix this in the near future?
@HarveyMoony You can see my temporary solution - https://codesandbox.io/s/407zvllxw4
I've typed a separate component that holds the message queue. However, the delay between messages is realized using the usual timeout. As for me - this is not the best and not a tedious decision.
But I think it would be better if this functionality was provided by the <v-snackbar>
component
@cawa-93 Please excuse me if I understood the problem incorrectly but why don't you simply use :value
and @input
instead of v-model
on <v-snackbar/>
?
Here is my working solution to handle this specific problem:
<template>
<v-snackbar :value="shown" @input="$emit('close')">
Hello world! this is an awesome message!
<v-btn @click="$emit('close')">Close Me!</v-btn>
</v-snackbar>
</template>
<script>
export default {
name : 'Notify',
props: {
shown: {
type : Boolean,
default: false,
},
},
}
</script>
And call it like this:
<template>
<div>
<v-btn @click="showSnackbar = true">Show the notification</v-btn>
<notify :shown="showSnackbar" @close="showSnackbar = false"/> <!-- @close will be called whether snackbar is timed-out or is manually closed -->
</div>
</template>
<script>
export default {
name : 'SomeContainer',
data : () => {
return ({
showSnackbar: false
})
},
}
</script>
Well you can queue it of course.
@AmirrezaNasiri I do not know how it works now. At the time when I created this issue, the @input
fired before exit animation completed.
If you have any additional questions, please reach out to us in our Discord community.
I used Provide and inject instead of using Vuex and this is my solution
https://codesandbox.io/s/jz3yz3x93w
Most helpful comment
@HarveyMoony You can see my temporary solution - https://codesandbox.io/s/407zvllxw4
I've typed a separate component that holds the message queue. However, the delay between messages is realized using the usual timeout. As for me - this is not the best and not a tedious decision.
But I think it would be better if this functionality was provided by the
<v-snackbar>
component