Vue.js 检测vuex状态更改以在nuxt布局内执行方法
我正在尝试在页面或vue组件中完成表单提交后显示vuetify snackbar警报。我使用vuex存储管理警报类型和消息 my numxt app/store/alerts.jsVue.js 检测vuex状态更改以在nuxt布局内执行方法,vue.js,vuejs2,vuex,nuxt.js,Vue.js,Vuejs2,Vuex,Nuxt.js,我正在尝试在页面或vue组件中完成表单提交后显示vuetify snackbar警报。我使用vuex存储管理警报类型和消息 my numxt app/store/alerts.js export const state = () => ({ message: '', type: '' }); export const getters = { hasAlert(state) { return state.message !== ''; },
export const state = () => ({
message: '',
type: ''
});
export const getters = {
hasAlert(state) {
return state.message !== '';
},
alertMessage(state) {
return state.message;
},
alertType(state) {
return state.type;
}
};
export const mutations = {
SET_ALERT(state, payload) {
state.type = payload.type;
state.message = payload.message;
}
};
export const actions = {
setAlert({commit}, payload) {
commit('SET_ALERT', payload);
},
clearAlert({commit}) {
commit('SET_ALERT', {});
}
};
import Vue from 'vue';
import {mapGetters} from 'vuex';
const Alert = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
hasAlert: 'alerts/hasAlert',
alertType: 'alerts/alertType',
alertMessage: 'alerts/alertMessage'
})
}
});
}
};
Vue.use(Alert);
我创建了一个nuxt插件,在我的应用程序中全局访问getter
my nuxt app/plugins/alert.js
export const state = () => ({
message: '',
type: ''
});
export const getters = {
hasAlert(state) {
return state.message !== '';
},
alertMessage(state) {
return state.message;
},
alertType(state) {
return state.type;
}
};
export const mutations = {
SET_ALERT(state, payload) {
state.type = payload.type;
state.message = payload.message;
}
};
export const actions = {
setAlert({commit}, payload) {
commit('SET_ALERT', payload);
},
clearAlert({commit}) {
commit('SET_ALERT', {});
}
};
import Vue from 'vue';
import {mapGetters} from 'vuex';
const Alert = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
hasAlert: 'alerts/hasAlert',
alertType: 'alerts/alertType',
alertMessage: 'alerts/alertMessage'
})
}
});
}
};
Vue.use(Alert);
在我的AccountForm
组件提交方法中,我将警报信息发送到存储区,如下所示
my nuxt app/components/form/AccountForm.vue
...
methods: {
async submit () {
try {
await this.$axios.patch("/settings/profile", this.form);
this.$store.dispatch('alerts/setAlert', {
type: 'success',
message: 'You have successfully updated your information.'
});
} catch (e) {
}
}
},
...
}
...
<template>
...
<v-snackbar
:timeout="snackbar.timeout"
:color="snackbar.color"
:top="snackbar.y === 'top'"
:bottom="snackbar.y === 'bottom'"
:right="snackbar.x === 'right'"
:left="snackbar.x === 'left'"
:multi-line="snackbar.mode === 'multi-line'"
:vertical="snackbar.mode === 'vertical'"
v-model="snackbar.show"
>
{{ snackbar.text }}
<v-btn flat icon dark @click.native="snackbar.show = false">
<v-icon>close</v-icon>
</v-btn>
</v-snackbar>
...
</template>
<script>
...
data: () => ({
snackbar: {
show: false,
y: 'top',
x: null,
mode: '',
timeout: 6000,
color: '',
text: ''
},
}),
computed: {
availableAlert: function () {
return this.hasAlert;
}
},
watch: {
availableAlert: function(alert) {
if(alert) {
this.showAlert(this.alertType, this.alertMessage);
this.$store.dispatch('alerts/clearAlert');
}
}
},
methods: {
showAlert(type, message) {
this.snackbar.show = true;
this.snackbar.color = type;
this.snackbar.text = message;
}
}
</script>
这个AccountForm.vue
组件是profile.vue
页面的子组件,它显然位于我项目的pages文件夹中。此外,我还将dashboard.vue
布局扩展到了这个profile.vue
页面,并将页面目录中的大部分页面作为一个通用布局。因此,我将snackbar组件添加到dashboard
布局中,以便在需要时显示警报消息
我的nuxt应用程序/布局/仪表板.vue
...
methods: {
async submit () {
try {
await this.$axios.patch("/settings/profile", this.form);
this.$store.dispatch('alerts/setAlert', {
type: 'success',
message: 'You have successfully updated your information.'
});
} catch (e) {
}
}
},
...
}
...
<template>
...
<v-snackbar
:timeout="snackbar.timeout"
:color="snackbar.color"
:top="snackbar.y === 'top'"
:bottom="snackbar.y === 'bottom'"
:right="snackbar.x === 'right'"
:left="snackbar.x === 'left'"
:multi-line="snackbar.mode === 'multi-line'"
:vertical="snackbar.mode === 'vertical'"
v-model="snackbar.show"
>
{{ snackbar.text }}
<v-btn flat icon dark @click.native="snackbar.show = false">
<v-icon>close</v-icon>
</v-btn>
</v-snackbar>
...
</template>
<script>
...
data: () => ({
snackbar: {
show: false,
y: 'top',
x: null,
mode: '',
timeout: 6000,
color: '',
text: ''
},
}),
computed: {
availableAlert: function () {
return this.hasAlert;
}
},
watch: {
availableAlert: function(alert) {
if(alert) {
this.showAlert(this.alertType, this.alertMessage);
this.$store.dispatch('alerts/clearAlert');
}
}
},
methods: {
showAlert(type, message) {
this.snackbar.show = true;
this.snackbar.color = type;
this.snackbar.text = message;
}
}
</script>
...
{{snackbar.text}
关闭
...
...
数据:()=>({
小吃条:{
秀:假,,
y:'顶',
x:null,
模式:“”,
超时:6000,
颜色:'',
文本:“”
},
}),
计算:{
AvailableAllert:函数(){
返回此.hasAlert;
}
},
观察:{
可用警报:功能(警报){
如果(警报){
this.showarter(this.alertType,this.alertMessage);
此.$store.dispatch('alerts/clearAlert');
}
}
},
方法:{
showAlert(类型、消息){
this.snackbar.show=true;
this.snackbar.color=类型;
this.snackbar.text=消息;
}
}
我第一次提交表单时收到警报消息,之后我必须重新加载页面,然后提交以获得警报。请告诉我一种检测vuex状态变化的方法,并相应地触发
仪表板中的showart
方法。vue
。这很可能是您检查hasAlert
您的clearAlert
传递一个空对象,您的setAlert
正在尝试分配该空对象的属性,而您的hasAlert
正在检查它是否为空字符串
如果您将clearAlert更改为:
clearAlert({commit}) {
commit('SET_ALERT', { message: '', type: '' });
}
这应该可以解决你的问题。在codesandbox上做一个例子要比阅读并试图找出答案容易得多。是的,它确实解决了问题。多么愚蠢的错误(