Vuejs2 axios突变:更新对象

Vuejs2 axios突变:更新对象,vuejs2,Vuejs2,我有以下user.js文件可以“工作”,但需要改进: import * as mutationTypes from "../mutation-types"; import user from "./user_data"; export const state = user; export const getters = { user: (state) => state }; export const mutations = { [mut

我有以下user.js文件可以“工作”,但需要改进:

import * as mutationTypes from "../mutation-types";
import user from "./user_data";

export const state = user;

export const getters = {
  user: (state) => state
};

export const mutations = {
  [mutationTypes.SET_USER]: (state, payload) => {
    state.username = payload.username;
    state.avatar=payload.avatar;
    state.locale=payload.locale;
    state.currency=payload.currency;
    state.userid=payload.userid;
  }
};

export const actions = {
  setUser: ({ commit }, payload) => {
    commit(mutationTypes.SET_USER, payload);
  }
};
我通过axios接收代表完整用户的有效负载,因此状态为:

payload:{
    userid: "EA7FD2025132E3254A11FE70E9746A52",
    username: "boss",
    level:  6,
    active: true,
    company:'mySite ltd',
    landingpage:'dashboard',
    locale:'es',
    currency:'eur',
    subscriptionlevel:'',
    subscriptionexpiry:'',
    credits:0,
    name: "John Doe",
    email: "john.doe@mysite.com",
    avatar: "/static/avatar/john.jpg",
    job: "mySite - FOUNDER & CEO",
  }
如何在不更新单个子参数的情况下完全更新状态 例如:

export const mutations = {
  [mutationTypes.SET_USER]: (state, payload) => {
    state = payload;
  }
};
我试过了

state = Object.assign({}, payload)
但它不起作用:-(

这里是vuex状态:

Vuex中的状态和相关功能(突变、getter等)被认为包含多条信息和多个片段,可用于管理应用程序状态

一次改变整个状态是一个不寻常的用例:如果可能的话,我会回答自己

出于@Dan在其回答中解释的原因,当您在
mutation
方法中将一个Javascript对象指向一个新对象时,原始对象不会更改,而是在您的示例中传递给该方法的引用指向
payload
。因此,原始对象不会更改。Dan Abramov有一个很大的优势在他的博客文章中,有一篇关于变异的文章:请,如果你有时间,我建议你复习一下

因此,与其尝试变异整个
状态
,不如只变异一个片段,比如
state.user

要使其正常工作,您需要如下初始化Vuex
状态
(假设从外部文件导入了
用户
):

导出常量状态={
用户:用户
}
或者更简洁地说,使用:

导出常量状态={
用户
}
您可以根据需要在此处定义尽可能多的属性,以反映实际的应用程序状态,并用初始值填充它们

然后,您可以在相应的
突变上安全地突变该切片:

导出常量突变={
[mutationTypes.SET_USER]:(状态、有效负载)=>{
state.user=有效载荷;
}
};
您还需要修改相关的
getter

export const getters={
用户:(状态)=>state.user
};

为什么不起作用

每当您重新分配一个已经包含对象的变量时,它不会更改现有对象,只会将该变量指向一个新对象。旧的引用连接将丢失。因此,在变异中重新分配
状态
对实际的基础
状态
对象没有任何影响。如果使用
=/cod,则没有任何区别e> ,
对象。分配
,或
扩展运算符

最好将用户对象置于类似于
状态的状态。user

state = payload  // ❌ Only reassigns the variable reference, no changes to original
查看它的另一种方法是记住函数中的
状态
不一定总是与模块中的
状态
相同,事实上它是相同的

不直接使用
状态
对象的一些原因:

  • 很难在突变中改变它
  • 更难与
    mapState
    helper一起使用
  • 代码可读性/可测试性

  • store.replaceState
    如果您仍然希望以这种方式使用
    状态
    ,而您没有使用Vuex模块,则有时可以非常轻松地使用。也可以使用模块来完成,但这有点棘手:

    导出常量突变={
    [mutationTypes.SET_USER]:(状态、有效负载)=>{
    此.replaceState(有效载荷);
    }
    };
    
    hmm..这是因为对象不是原始数据类型,因此它仅被引用?好吧,它不起作用,但会根据您的建议尝试修改结构,直到不起作用:返回
    Uncaught(承诺中)TypeError:无法读取undefined的属性'replaceState'。
    谢谢。我不确定您是如何为未定义的
    设置存储的,但这没关系,因为使用Vuex模块时,
    replaceState
    有点棘手。但正如我所说的,我建议不要像那样直接使用
    state
    。回答您的问题第一个问题:原语也是如此。任何变量重新分配都不会对用于指向的变量产生任何影响。否..不起作用:-(无论如何,谢谢@Joe。问题可能与Vue维护状态的方式有关,Dan在其回答中也解释了这一点。请尝试建议的新方法。您好!此解决方案似乎有效。实际上,
    用户
    是一个“sub”状态由于它在单独的.js文件中,我想,至少要了解它是如何工作的,将它更改为
    state.user
    ,但到目前为止我的所有尝试都失败了:-(刚刚添加了vuex statusAnd@Joe的屏幕截图,如果您尝试
    state.user=payload
    ,它将不起作用?
    state.user = payload  // ✅ Changing a reference property via the parent reference