ホーム > Vue > How to Define Vuetify Snackbar in Vuex for Reusability Anywhere
Vue

How to Define Vuetify Snackbar in Vuex for Reusability Anywhere

Thank you for your continued support.
This article contains advertisements that help fund our operations.

⇨ Click here for the table of contents for Laravel articles

Vuetify's Snackbar is often used when saving or deleting data.

So, let's define it in Vuex so that it can be used anywhere.

What is Vuetify Snackbar

Vuetify is a UI framework for Vue.

It provides useful components, making it easy to implement a convenient UI with copy-paste.

Also, by passing content through props, you can easily change the settings.

⇨ How to Use Props in Vue and Basic Writing

When v-model is set to True, Snackbar allows you to display a flash message for a few seconds.

It looks like this.

Image of Snackbar

Official Vuetify Documentation

Implementing Snackbar in Vuex

To use Vuex, refer to this article.

⇨ How to Use Vuex in Laravel

Directory Structure

  1. Create a js/store/index.js file.
  2. Create a js/store/modules/util.js file.

Follow the directory structure as shown in the screenshot.

Writing in index.js

The filename can be anything.

This time, import util.js and define it in the modules.

import Vue from "vue"
import Vuex from "vuex"
import util from "./modules/util"

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    util,
  },
})

Writing in util.js

Define functions that can be called from anywhere in util.js.

Define the function in actions. Write the description to change the state in mutations.

const getters = {}

const state = {
  // Define the initial state
  text: "",
  snackbar: false,
}

const mutations = {
  // Change the state in mutations
  setSnackbar: (state, text) => {
    state.snackbar = true
    state.text = text
  },
  unsetSnackbar: () => {
    state.snackbar = false
    state.text = ""
  },
}

const actions = {
  // Function to display the snackbar (the first argument is the text to display)
  openSnackbar: ({ commit }, text) => {
    // Trigger mutations. Pass the text content as an argument
    commit("setSnackbar", text)
  },
  // Function to hide the snackbar
  closeSnackbar: ({ commit }) => {
    commit("unsetSnackbar")
  },
}

export default {
  namespaced: true,
  getters,
  state,
  mutations,
  actions,
}

This completes the Vuex description.

Calling in VueComponent

HomeComponent.vue

<template>
  <div>
    <v-btn @click="openSnackbar('This is a snackbar')"
      >Click the button to trigger the snackbar</v-btn
    >
    <!-- Displays for a while when v-model becomes true -->
    <v-snackbar v-model="$store.state.util.snackbar">
      <!-- Text to display in the Snackbar -->
      {{ $store.state.util.text }}
      <template v-slot:action="{ attrs }">
        <!-- Close when the button is clicked -->
        <v-btn color="pink" text v-bind="attrs" @click="closeSnackbar">
          Close
        </v-btn>
      </template>
    </v-snackbar>
  </div>
</template>

<script>
  import { mapActions } from "vuex";
  export default {
    methods: {
      // Declare using mapActions to use the functions defined in Vuex.
      // There are other ways to use it, but by using mapActions, you can call the function as "openSnackbar".
      ...mapActions("util", ["openSnackbar", "closeSnackbar"]),
    },
  };
</script>

Let's press the button immediately.

Image of Snackbar

If it is displayed like this, then it is okay.

Defining the Display Part in AppComponent Makes Writing Even Easier

It becomes cumbersome to define the Snackbar in each component every time.

So, define v-snackbar in a common component to be used.

AppComponent.vue

<template>
  <v-app>
    <router-view></router-view>
    <v-snackbar v-model="$store.state.util.snackbar">
      <!-- Text to display in the Snackbar -->
      {{ $store.state.util.text }}
      <template v-slot:action="{ attrs }">
        <!-- Close when the button is clicked -->
        <v-btn color="pink" text v-bind="attrs" @click="closeSnackbar">
          Close
        </v-btn>
      </template>
    </v-snackbar>
  </v-app>
</template>

By defining it in the AppComponent or common components used, there is no need to repeatedly write the display part.

Example of Displaying Snackbar when Communication is Successful with axios

PostComponent.vue

  <script>
  import { mapActions } from "vuex";
  export default {
    methods: {
      ...mapActions("util", ["openSnackbar", "closeSnackbar"]),
      post: function(){
        axios.post('/post',{
          text: 'Text'
        }).then(({data})=>{
          this.openSnackbar('Sent!');
        }).catch(err=>{
          console.log(err)
        })
      }
    },
  }
</script>

Define and call the openSnackbar with mapActions,

and after a successful axios.post, call that function (after then),

which makes it OK.

Within '', unlike in the template, 'this.' is required, so be careful.

Summary

How was it?

I defined the display of the Snackbar in Vuex to easily call it from any component.

By applying this, for example, you can easily call the loading circle as well.

Vue, without any settings, is very poor in user usability because the button does not respond when clicked.

Therefore, it is important to add something to enhance the user usability for each click event.

This time, I introduced the useful Snackbar for "events succeeded or failed" in such a situation.

Please try and use it.

Please Provide Feedback
We would appreciate your feedback on this article. Feel free to leave a comment on any relevant YouTube video or reach out through the contact form. Thank you!