Vuejs2 如何使用vuex正确处理可编辑的复杂对象(嵌套)?

Vuejs2 如何使用vuex正确处理可编辑的复杂对象(嵌套)?,vuejs2,vuex,Vuejs2,Vuex,Vuex非常适合显示复杂的数据,并进行复杂的变异(比如在一棵树上添加一个节点,在整个存储中都会产生影响等等),然而,对我来说,在复杂对象上处理“简单”的变异就像是一件痛苦的事 我面临的一个用例(相当)简单:我有一个显示列表对象(具有嵌套属性和数组)的组件。每个属性都是可编辑的。每个对象都显示一个子构件。(我需要在叶属性上使用v-model) 另一个用例是使用组件的方法打开的模式对话框,该对话框允许编辑对象的某些属性/嵌套属性(而且,我需要在叶属性上使用v-model) 目前,我是这样做的: 在显

Vuex非常适合显示复杂的数据,并进行复杂的变异(比如在一棵树上添加一个节点,在整个存储中都会产生影响等等),然而,对我来说,在复杂对象上处理“简单”的变异就像是一件痛苦的事

我面临的一个用例(相当)简单:我有一个显示列表对象(具有嵌套属性和数组)的组件。每个属性都是可编辑的。每个对象都显示一个子构件。(我需要在叶属性上使用v-model)

另一个用例是使用组件的方法打开的模式对话框,该对话框允许编辑对象的某些属性/嵌套属性(而且,我需要在叶属性上使用v-model)

目前,我是这样做的: 在显示/编辑对象的组件中,我将组件的
数据
放入可以编辑的对象的“骨架”(存在所有嵌套属性的对象,但所有叶都设置为
null
)。然后,当模式打开时,或者组件应该显示/使对象可编辑时,我只需将对象(使用递归函数)深度复制到
数据
对象,然后使用
deep
选项将数据对象观察到
true
,并在每次更改时提交

这感觉有点不对劲,需要付出相当大的努力才能奏效

我喜欢突变跟踪系统,我想在每次对嵌套属性进行修改时提交我的整个对象。如果不需要编写这么多代码就可以做到这一点,那将是非常棒的(我想知道,如果为了一个简单的全局Vue组件存储而放弃vuex,并用漂亮的变异系统换取简单的代码,这是否值得)

那么,有没有一种“标准”方式或“推荐方式”……或者仅仅是一种“聪明”的方式而不需要这样的努力

存储状态的示例:

state = {
  foo : [
    bar : {
      users : [
        {
          name : '',
          adddr : '',
          needs : ['a', 'b', 'c'],
          baz : [
            {
              k1 : v1,
              k2 : v2,
              k3 : [1,2,3,4,5],
            },
            //...
          ]
        },
        //...
      ]
    }
  ]
}

…我希望每次提交整个用户。

假设您有一个复杂的嵌套对象,如下所示:

{
  super: {
    nested: {
      object: {
        to: {
          be: {
            updated: 'foo'
          }
        }
      }
    }
  }
}
现在,您可能需要更新特定密钥的操作:

import * as types        from '../mutation-types'
import * as defaultStore from '../defaultStore'

export default {

  namespaced: true,

  state: defaultStore.complexObject,

  getters: {
    getSettings: state => state
  },

  mutations: {
    [types.UPDATE_SUPER_NESTED_OBJECT] (state, payload) {
      state.super.nested.object.to.be.updated = payload
    }
  },

  actions: {
    updateSuperNestedObject (store, payload) {
      return store.commit(types.UPDATE_SUPER_NESTED_OBJECT, payload)
    }
  }

}
在您的组件中:

import { mapActions } from 'vuex'

export default {

 computed: {
   ...mapActions('<modulename>', ['updateSuperNestedObject'])
 }

 methods: {
   handleUpdate(payload) {
     return this.updateSuperNestedObject('bar')
   }
 }

}
从“vuex”导入{mapActions}
导出默认值{
计算:{
…映射操作(“”,['updateSuperNestedObject'])
}
方法:{
手动更新(有效载荷){
返回此.updateSuperNestedObject('bar'))
}
}
}

希望有帮助

我建议这样使用:

  • 组件包含要更新的属性的完整路径(这将被激发)
  • 在vuex中,使用lodash或其他类似工具使用完整路径设置属性
  • 组件
    
    导出默认值{
    方法:{
    更新:函数(属性、值){
    此.store.dispatch(更新复杂对象,{property,value})
    }
    }
    }
    
    嗯。。。这个问题让我非常恼火,以至于我写了一个模块来处理所有这些复杂的案例。你可以在这里找到它:

    然后,我们可以简单地写下这种成分:

    从“vue数据代理”导入vueDataProxy;
    导出默认值{
    道具:{
    用户标识;
    }
    计算:{
    …vueDataProxy({
    用户:{
    fetch(){
    返回此.store.state.foo.bar.users[this.user_ind];
    },
    提交(val){
    //此处,val为完整对象(如果注入反应性)
    //取回
    this.$store.commit('updateUser',{ind:this.user_ind,val}
    }
    }
    },
    //...
    }
    
    …假设您有一个名为
    updateUser(state,{ind,val}){/*…*/}


    …然后,它将在任何深度的每次修改上提交

    您可以发布一些Vuex实例的示例吗?不,您只针对叶子。我想提交一个完整的“子树”来保持反应性(但我添加了一个示例来说明它,并且(如果是随机数据,则事件)“复杂”足以证明我不能为每个键进行变异我认为它会更新,但是你如何将值绑定到输入?(无论如何,我认为它比我当前的解决方案更“黑客化”)您好,您需要创建一个简单的组件,这需要是次要的可能表示形式,例如叶。检查Vuetifyjs,有一个可扩展的列表,可能可以帮助您。检查扩展列表