VuetifyのSnackbarをVuexで定義してどこでも使い回す方法
いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。
目次
Vuetify の Snackbar は、データを保存した時や削除した時など、何度も使うことが多いです。
なので、どこでも使えるように、Vuex で定義していきましょう。
Vuetify の Snackbar とは
Vuetify は、Vue の UI フ レームワークです。
便利なコンポーネントが用意されており、コピペで簡単に便利な UI を実装することができます。
また、props で受け渡す内容によって、設定を簡単に変更させることができます。
Snackbar は、v-model を True にすると数秒間、フラッシュメッセージを出すことができるコンポーネントになります。
こういう表示です。
Snackbar を Vuex で実装
Vuex が使えるようにするには、こちらの記事に書いています。
ディレクトリ構成
①js/store/index.js ファイルを作成します。
②js/store/modules/util.js ファイルを作成します。
スクショのようなディレクトリ構成でいきます。
index.js に書く
ファイル名はなんでも良いです。
今回は、util.js を import して、modules に定義してください。
import Vue from "vue"
import Vuex from "vuex"
import util from "./modules/util"
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
util,
},
})
util.js に書く
util.js には、どこからでも呼べる関数を定義します。
actions に関数を定義する。mutations に state を変更する記述を書く。という感じでやっています。
const getters = {}
const state = {
//初期状態を定義
text: "",
snackbar: false,
}
const mutations = {
//stateをmutationsで変更する。
setSnackbar: (state, text) => {
state.snackbar = true
state.text = text
},
unsetSnackbar: () => {
state.snackbar = false
state.text = ""
},
}
const actions = {
//スナックバーを表示させる時の関数(第一引数に表示するテキストの内容)
openSnackbar: ({ commit }, text) => {
//mutationsを発動させる。テキストの内容を引数で持たせる
//commit('mutatiuonsの関数名')でmutationsを発動させられる
commit("setSnackbar", text)
},
//スナックバーを非表示にする関数
closeSnackbar: ({ commit }) => {
commit("unsetSnackbar")
},
}
export default {
namespaced: true,
getters,
state,
mutations,
actions,
}
これで Vuex の記述は完了です。
VueComponent で呼び出す
HomeComponent.vue
<template>
<div>
<v-btn @click="openSnackbar('すなっくばーだよ')"
>ボタンを押したらスナックバーが発動</v-btn
>
<!-- v-modelがtrueになったらしばらく表示される -->
<v-snackbar v-model="$store.state.util.snackbar">
<!-- Snackbar内に表示するテキスト -->
{{ $store.state.util.text }}
<template v-slot:action="{ attrs }">
<!-- ボタンを押したらcloseする -->
<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: {
//mapActionsでVuexに記述した関数を使うっていう宣言をします。
//他にも使う方法自体はありますが、mapActionsを使うことにより「openSnackbar」という関数名で呼び出せるようになります。
...mapActions("util", ["openSnackbar", "closeSnackbar"]),
},
};
</script>
早速ボタンを押してみましょう
このように表示されたら OK です。
AppComponent で表示の部分を定義しておけば更に記述が簡単になる
毎回、Component で Snackbar を定義するのもめんどうになります。
なので、共通のコンポーネントに v-snackbar を定義します。
AppComponent.vue
<template>
<v-app>
<router-view></router-view>
<v-snackbar v-model="$store.state.util.snackbar">
<!-- Snackbar内に表示するテキスト -->
{{ $store.state.util.text }}
<template v-slot:action="{ attrs }">
<!-- ボタンを押したらcloseする -->
<v-btn color="pink" text v-bind="attrs" @click="closeSnackbar">
Close
</v-btn>
</template>
</v-snackbar>
</v-app>
</template>
このようにおおもとの AppComponent や、共通で使っている Component などに定義しておけば、表示の部分は何度も記述する必要がなくなります。
axios などで通信が成功した時に Snackbar を表示する例
PostComponent.vue
<script>
import { mapActions } from "vuex";
export default {
methods: {
...mapActions("util", ["openSnackbar", "closeSnackbar"]),
post: function(){
axios.post('/post',{
text: 'テキスト'
}).then(({data})=>{
this.openSnackbar('送信しました!');
}).catch(err=>{
console.log(err)
})
}
},
}
</script>
このように mapActions で openSnackbar を使いますよ、と定義して、
axios.post が成功した後(then のあと)にその関数を呼び出せば OK です。
''内では、template 内とは異なり、this.が必要になるので注意してください。
まとめ
いかがでしたか?
Vuex で Snackbar の表示を定義してどこのコンポーネントからでも簡単に呼び出せるようにしました。
これを応用すると、例えば、loading のサークルも簡単に呼び出すことができます。
Vue は、何も設定しないとボタ ンを押しても反応がないため、ユーザビリティが非常に悪いです。
なので、クリックイベント1つ1つにユーザビリティを高める何かをつけてあげることが大事になってくると思います。
今回は、そんな中でも、「イベントが成功したとき、失敗した時」に便利な Snackbar の紹介をしました。
ぜひ使ってみてください。