不要在突变处理程序(Vuetify snackbar)之外突变vuex存储状态



我有一个来自Vuetify的小吃条。它在default.vue中,vuex存储控制v-modelmessagecolor:

默认SnackBar.vue

<template>
<v-container>
<v-snackbar
v-model="snackbarProperties.show"
:color="snackbarProperties.color"
timeout="7000"
multi-line
>
{{ snackbarProperties.message }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="hideSnackbar"
>
Close
</v-btn>
</template>
</v-snackbar>
</v-container>
</template>
<script>
import { mapActions } from "vuex";
import { mapGetters } from "vuex";
export default {
methods :{
...mapActions("Snackbar",["showSnackbar","hideSnackbar"]),
},
computed: {
...mapGetters("Snackbar",["snackbarProperties"])
},
}
</script>

Snackbar.js

export const state = () => ({
message: "",
color: "",
show: false,
});
export const getters = {
snackbarProperties: state => {
return state;
},

}
export const mutations = {
showSnackbar: (state, payload) => {
state.message = payload.message;
state.color = payload.color;
state.show = true;
},
hideSnackbar: (state) => {
state.message = "";
state.color = ""
state.show = false;
},
}
export const actions = {
showSnackbar({ commit }, payload) {
commit('showSnackbar', payload)
},
hideSnackbar({ commit }) {
commit('hideSnackbar')
}
}

当我调用showSnackbar({...})时,条显示正确,没有错误,但当它消失时(达到超时(,得到这个错误,所有东西都会崩溃

不要在突变处理程序之外突变vuex存储状态

我认为这是因为当条消失时,组件会更改它所连接的v-model的值,但我不知道如何解决这个问题。

我从这个vue论坛找到了答案:

使用一个带有setTimeout代码的操作进行突变。突变应该是同步的,这就是为什么在它们中使用超时就是发出警告。

我已经更新了Snackbar.js以适应:

export const state = () => ({
message: "",
color: "",
show: false,
});
export const getters = {
snackbarProperties: state => {
return state;
},

}
export const mutations = {
showSnackbar: (state, payload) => {
state.message = payload.message;
state.color = payload.color;
state.show = true;

},
hideSnackbar: (state) => {
state.message = "";
state.color = ""
state.show = false;
},
}
export const actions = {
showSnackbar({ commit }, payload) {
commit('showSnackbar', payload)
setTimeout(() => {
commit('hideSnackbar')
}, 500);
},
hideSnackbar({ commit }) {
commit('hideSnackbar')
}
}

如果需要显示多个,请尝试此操作

<template>
<div class="text-center">
<v-snackbar
v-for="(snackbar, index) in snackbars.snackbars.filter(
(s) => s.isVisible
)"
:key="snackbar.text + Math.random()"
v-model="snackbar.isVisible"
:color="snackbar.color"
:timeout="-1"
:right="true"
:top="true"
:style="`top: ${index * 60}px`"
>
<v-row no-gutters>
<v-col md="11" sm="11">
{{ snackbar.text }}
</v-col>
<v-col md="1" sm="1">
<v-btn class="mx-2" icon  small @click="hideNotify(index)">
<v-icon color="error"> mdi-close </v-icon>
</v-btn>
</v-col>
</v-row>
</v-snackbar>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState({ snackbars: 'notification' }),
},
methods: {
hideNotify(index) {
this.$store.dispatch('notification/HIDE_NOTIFY_WITH_INDEX',index)
},
},
}
</script>

将其作为notification.js 添加到vuex中

export const state = () => ({
snackbars: [],
})
export const mutations = {
SET_SNACKBAR(state, snackbar) {
state.snackbars = state.snackbars.concat(snackbar)
},
HIDE_NOTIFY_WITH_INDEX(state,index) {
if (index in state.snackbars) {
state.snackbars.splice(index, 1)
}
},
HIDE_NOTIFY(state) {
state.snackbars = []
},
}
export const actions = {
SET_SNACKBAR({ commit }, snackbar) {
snackbar.isVisible = true
snackbar.color = snackbar.color || 'dark'
commit('SET_SNACKBAR', snackbar)
setTimeout(() => {
commit('HIDE_NOTIFY')
}, 6000)
},
HIDE_NOTIFY_WITH_INDEX({ commit },index) {
commit('HIDE_NOTIFY_WITH_INDEX',index)
},
}

最新更新