我有以下情况:
组件文本字段:
<v-text-field
v-model="form.profile.mobile_business"
label="Mobile"
prepend-inner-icon="mdi-cellphone"
></v-text-field>
我通过以下方式获取当前值:
data() {
return {
form: {
profile: JSON.parse(JSON.stringify(this.$store.getters["user/Profile"])),
},
};
},
我有一个调用此方法的提交按钮:
updateUserProfile() {
this.$store.dispatch("user/updateProfile", this.form.profile);
}
一切正常。在我的商店调度中,我进行API调用并通过我的突变来更新商店:
context.commit('UPDATE_PROFILE', profile);
在执行此步骤之前没有错误。
但是,如果我再次更改表单输入-在按下提交按钮后,我得到:
vuex:请勿在突变之外变异vuex存储状态
但是我不想仅在更改表单输入中的值时更改vuex存储。 仅当有人点击“提交”按钮时,它才应该更新。
答案 0 :(得分:0)
v-model
提供2路数据绑定。更改视图中的任何内容都会自动尝试直接更新模型,而不是通过突变。值得庆幸的是,Vue允许对计算属性使用get
和set
来帮助我们克服这些困难。
您应该在文本字段组件上执行的操作是使用get
和set
方法添加一个计算属性。看起来像这样:
computed: {
userProfile: {
get() {
JSON.parse(JSON.stringify(this.$store.getters["user/Profile"]));
},
set() {
// only commit the changes to the form, do not submit the action that calls the API here.
this.$store.commit("user/updateProfile", this.form.profile)
}
}
然后应将您的v-model属性设置为此新创建的属性,并且任何“设置”操作(读取:用户更改输入值)都将调用该操作,而不是尝试直接在Store中设置值
这是一个实时示例:CodePen
答案 1 :(得分:0)
我这样解决了:
form: {
profile: _.cloneDeep(this.$store.getters['user/Profile'])
},
并添加了一个监视处理程序:
form: {
handler: _.debounce(function (form) {
console.log("watch fired");
}, 500), deep: true
}
因此,如果用户更改值,则什么都不会发生(我的console.log操作除外)。 如果他按下“提交”按钮,则将触发商店调度动作。