kl3sk
kl3sk

Reputation: 136

Vuetify Snackbar leave event

I manage to implement a global Vuetify Snackbar.

My problem is to detect when the snackbar close. I read that this component support Vue transition event since 1.2. But it work only on the enter event not the leave ones.

here a fiddle for comprehension.

<transition @before-enter="beforeEnter" @before-leave="beforeLeave" @after-enter="afterEnter" @after-leave="afterLeave" @leave="leave">
    <v-snackbar v-model="snackbar" top right>
        Hello
        <v-btn @click="snackbar = false" dark>Close</v-btn>
    </v-snackbar>
</transition>

Upvotes: 1

Views: 3877

Answers (2)

j4ys0n
j4ys0n

Reputation: 730

You can use get and set methods to handle reading and updating the bound model separately.

I made a generic snackbar component that can be triggered from any other component. I'm using Vuex, vue-property-decorator and typescript here, so adjust accordingly.

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<template>
  <v-snackbar v-model="snackbar" max-width="100%">
    <template v-slot:action="{ attrs }">
      {{ text }}
      <v-btn color="primary" text fab v-bind="attrs">
        <v-icon dark @click="close()"> mdi-close-circle-outline </v-icon>
      </v-btn>
    </template>
  </v-snackbar>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component({})
export default class Snackbar extends Vue {

  get snackbar() {
    return this.$store.state.snackbar.show
  }

  set snackbar(show: boolean) {
    this.$store.dispatch('updateSnackbar', { show, text: '' })
  }

  get text() {
    return this.$store.state.snackbar.text
  }

  public close() {
    this.$store.dispatch('updateSnackbar', { show: false, text: '' })
  }
}
</script>

Upvotes: 0

Xavier Carol
Xavier Carol

Reputation: 101

I faced the same problem and solved this way:

export default {
  data: () => ({
    errorMessage: '',
    snackTimeout: 6000,
  }),
  watch: {
    errorMessage() {
      setTimeout(() => {
        this.clearErrorMessage();
      }, this.snackTimeout);
    },
  },
  methods: {
    setErrorMessage(message) {
      this.snackMessage = message;
    },
    clearErrorMessage() {
      this.snackMessage = '';
    },
  },
};
<template>
    <v-snackbar
      :value="errorMessage"
      :timeout="snackTimeout"
      top
    >
      {{ errorMessage }}
      <v-btn
        color="error"
        flat
        @click.stop="clearErrorMessage"
      >
        {{ 'close' }}
      </v-btn>
    </v-snackbar>
</template>
  • Define an attribute with the timeout and another with the message to show by the snackBar.
  • Define a function to set the message and another to clear it.
  • Define a watch for the message text and set a timer with the same timeout of the snackBar to clear it.
  • The snackBar appears only when the message is not empty.

Upvotes: 1

Related Questions