Vue.js 检测vuex状态更改以在nuxt布局内执行方法

Vue.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 !== ''; },

我正在尝试在页面或vue组件中完成表单提交后显示vuetify snackbar警报。我使用vuex存储管理警报类型和消息

my numxt app/store/alerts.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);
我创建了一个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上做一个例子要比阅读并试图找出答案容易得多。是的,它确实解决了问题。多么愚蠢的错误(