如何解决使用 Vue、Vuetify 和 Vuex 创建一个全局小吃店
我尝试创建一个全局小吃栏以在每次发生 axios http 错误时触发,我遵循了本教程:https://dev.to/stephannv/how-to-create-a-global-snackbar-using-nuxt-vuetify-and-vuex-1bda
但我不想使用 Nuxt,只想使用 Vue、Vuex 和 Vuetify,所以我尝试创建一个随处可用的插件,但出现以下错误:[vuex] unkNown mutation type: snackbar/showMessage
和 TypeError: Cannot read property '$snackbar' of undefined
。
这是我的代码:
src/main.js
import Vue from 'vue'
import router from "@/router";
import "./filters/filters";
import App from './App.vue'
import vuetify from "@/plugins/vuetify";
import VueSignaturePad from 'vue-signature-pad';
import axios from "axios";
import store from "@/store/snackbar";
import snackbarPlugin from "@/plugins/snackbar";
Vue.prototype.$http = axios;
Vue.config.productionTip = false
Vue.use(snackbarPlugin,{ store });
Vue.use(VueSignaturePad);
axios.interceptors.response.use(
function (response) {
return response;
},function (error) {
// handle error
if (error.response) {
this.$snackbar.showMessage({ content: error.response.data,color: 'error',timeout: 10000 })
}
});
new Vue({
router,store,vuetify,render: h => h(App)
}).$mount('#app')
src/store/snackbar.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
content: '',color: '',timeout: ''
},mutations: {
showMessage (state,payload) {
state.content = payload.content
state.color = payload.color
state.timeout = payload.timeout
}
}
});
export default store;
src/plugins/snackbar.js
const snackbarPlugin = {
install: (Vue,{store}) => {
if (!store) {
throw new Error('Please provide vuex store.');
}
Vue.prototype.$snackbar = {
showMessage: function ({
content = '',color = '',timeout = ''
}) {
store.commit(
'snackbar/showMessage',{content,color,timeout},{root: true}
);
}
};
},};
export default snackbarPlugin;
src/utils/Snackbar.vue
<template>
<v-snackbar v-model="show" :color="color" elevation="20">
{{ message }}
<v-btn color="accent" @click.native="show = false">
<v-icon>close</v-icon>
</v-btn>
</v-snackbar>
</template>
<script>
export default {
data() {
return {
show: false,message: "",color: "",timeout: 5000
};
},created () {
this.$store.subscribe((mutation,state) => {
if (mutation.type === 'snackbar/showMessage') {
this.message = state.snackbar.content
this.color = state.snackbar.color
this.timeout = state.snackbar.timeout
this.show = true
}
})
}
};
</script>
src/App.vue
<template>
<v-app>
<Snackbar></Snackbar>
<side-bar/>
<Header/>
<Main/>
</v-app>
</template>
<script>
import Snackbar from "@/utils/Snackbar";
import SideBar from "@/components/layouts/SideBar";
import Header from "@/components/layouts/Header";
import Main from "@/components/layouts/Main";
export default {
name: 'App',components: {
Snackbar,SideBar,Header,Main
},beforeMount() {
console.log('app')
this.getRole()
this.getEtats()
},methods: {
getRole() {
this.$http.get('/rol')
.then(response => {
let agent = {}
agent.role = response.data.data.role
agent.username = response.data.data.username
localStorage.setItem('badge.agent',JSON.stringify(agent))
})
.catch(function (error) {
console.log(error)
})
},getEtats() {
this.$http.get('/nyx/badge/demande/accesnro/etats')
.then(response => {
localStorage.setItem('badge.etats',JSON.stringify(response.data.data))
})
.catch(function (error) {
console.log(error)
})
}
}
}
</script>
我故意在 /role
路由上抛出 404 错误以显示小吃栏,但错误发生了。
请问您知道我在this.$snackbar.showMessage ({content: error.response.data,timeout: 10000 })
中调用 main.js
时出了什么问题吗?
解决方法
因为你没有使用 Vuex 模块 (https://vuex.vuejs.org/guide/modules.html),所以你应该调用没有小吃栏前缀的提交:
store.commit('showMessage',{
content,color,timeout}
);
查看此帖子 (Using vuejs plugin on the main.js file)。有说明,如何同时在main.js和App中使用plugin。
main.js
import Vue from "vue";
import router from "@/router";
import "./filters/filters";
import App from "./App.vue";
import vuetify from "@/plugins/vuetify";
import VueSignaturePad from "vue-signature-pad";
import axios from "axios";
import store from "@/store/snackbar";
import snackbarPlugin from "@/plugins/snackbar";
Vue.prototype.$http = axios;
Vue.config.productionTip = false;
Vue.use(snackbarPlugin,{ store });
Vue.use(VueSignaturePad);
axios.interceptors.response.use(
function(response) {
return response;
},function(error) {
// handle error
if (error.response) {
snackbarPlugin.showMessage({
content: error.response.data,color: "error",timeout: 10000
});
}
}
);
new Vue({
router,store,vuetify,render: h => h(App)
}).$mount("#app");
snackbar.js
import store from "../store/snackbar";
const snackbarPlugin = {
showMessage: ({ content = "",color = "",timeout = "" }) => {
store.commit("snackbar/showMessage",{ content,timeout },{ root: true });
},install: (Vue,{ store }) => {
if (!store) {
throw new Error("Please provide vuex store.");
}
Vue.prototype.$snackbar = snackbarPlugin;
}
};
export default snackbarPlugin;
main.js
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。