当我试图改变组件的输入文本时,我在控制台得到这个错误。
[vuex] do not mutate vuex store state outside mutation handlers.
我也用vuex的nuxt。
我的商店里有这个。
editor.js
export const state = () => ({
project_blocks: [{
id: null,
type: 'text-right',
content:{
title: 'Title 2',
text: 'Text 2',
}
},{
id: null,
type: 'text-left',
content:{
title: 'Title 1',
text: 'Text 1',
}
}],
});
export const mutations = {
SET_BLOCKS(state, blocks){
state.project_blocks = blocks;
},
};
export const getters = {
project_blocks(state){
return state.project_blocks;
}
};
在我的组件中,我有
Index.vue
<template>
<component v-for="(block, index) in project_blocks" :key="'module'+index" :block="block" :is="block.type"></component>
</template>
<script>
export default{
computed: {
project_blocks:{
get(){
return this.$store.getters['editor/project_blocks'];
},
set(val){
this.$store.commit('editor/SET_BLOCKS', val);
}
},
}
}
</script>
而在我的 "组件类型 "中,我有。
TextLeft.vue
<template>
<input type="text" v-model="block.content.title">
<input type="text" v-model="block.content.text">
</template>
<script>
export default{
props:['block']
}
</script>
当我试图更改这些输入文本时,我得到了这个错误。[vuex]不要在突变处理程序之外突变vuex的存储状态。 但我不知道如何解决:(
谢谢大家
错误信息在这里很有帮助(令人惊讶?当你v-model一个东西的时候,你是在说 "当这个输入改变的时候,修改我给你的这个东西的值"。
然而,正如错误所说的那样,这导致你直接突变了意在由Vuex存储的数据,这不是Vuex喜欢的方式。你应该使用你的突变。
编辑:下面的评论是错误的。谢谢,tao!附注:你的 set(val)
函数不应该出现在 computed
,它应该是在 methods
.
Vuex抱怨 v-model
直接改变状态,因为你正在向它传递一个getter(observable)。
为了正确地更新状态,你应该使用一个动作。添加一个执行该突变的动作,并在你的computed的setter中调度它。
computed: {
project_blocks:{
get(){
return this.$store.getters['editor/project_blocks'];
},
set(val){
this.$store.dispatch('editor/setBlocks', val);
}
}
}
storeeditor模块的setter里面。
actions: {
setBlocks({ commit }, payload) {
commit('SET_BLOCKS', payload);
}
}
突变保持不变。
中提供的例子是 表格 的子属性,才会有效。obj
. 如果他们使用 obj
本身(顶层的getter值),他们会得到和你一样的错误。
动作的要点是异步调用。你可以使用Vuex的突变,但不能直接改变状态,这是正确的不变性定义(你可以查看Vuex文档)。这是正确的不变性定义(你可以查看Vuex文档).我认为现在的主要问题是你的计算属性返回Vuex getters的结果,并且在项目上有Vuex监视者。而当你在改变它时--会显示错误。
我解决了这个错误!我在我的组件内部创建了一个数据值,我用两个突变分别改变这个值。
TextLeft.vue:
<template>
<input type="text" v-model="title">
<input type="text" v-model="text">
</template>
<script>
export default{
props:['block'],
data(){
title: this.block.content.title,
text: this.block.content.text
},
watch:{
title(val){
this.$store.commit('editor/SET_TITLE', { index: this.block.index,
title: val });
},
text(val){
this.$store.commit('editor/SET_TEXT', { index: this.block.index, text: val });
}
}
}
</script>