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

hl0*_*37_ 11 vuex vuejs2

Vuex 非常适合显示复杂的数据,并进行复杂的变更(比如向树添加一个节点,对整个商店的影响等),但是,对我来说,处理“简单”的变更感觉就像一个痛苦的过程在复杂的物体上。

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

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

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

这感觉有点不对,需要付出很大的努力才能让它发挥作用。

我喜欢突变可追溯系统,我希望每次对嵌套属性进行修改时提交整个对象。如果不用编写如此多的代码就可以实现,那真的很棒(我想知道为了一个简单的全局 Vue 组件商店而放弃 vuex 是否不值得......并权衡漂亮的突变系统对于简单的代码)

那么是否有“标准”方式或“推荐方式”......或者只是一种“智能”方式来做到这一点而不需要这样的努力?

商店状态示例:

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

...我想每次都提交整个用户。

小智 5

我建议以这种方式使用:

  1. 该组件包含要更新的属性的完整路径(这将被触发)
  2. 在 vuex 中使用 lodash 或其他类似工具使用完整路径设置属性。

成分

<template>
        <input v-on:change="update(‘object.nested.more.nested.attribute’, $event)" v-text:value="object.nested.mote.nested.attribute"></span>
</template>


<script>
 export default  {
  methods: {
    update: function (property, value) {
      this.$store.dispatch(UPDATE_COMPLEX_OBJECT, {property, value})
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

维克斯

import _ from 'lodash'

export default {
  namespaced: true,
  state: {
   myObject: {}
  },
  mutations: {
    [UPDATE_COMPLEX_OBJECT] (state, data) {
      _.set(state.myObject, data.property, data.value)
    }
  },
  actions: {
    [UPDATE_COMPLEX_OBJECT]: ({commit}, data) => {
      commit(UPDATE_COMPLEX_OBJECT, data)
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

如果有什么不清楚的地方,请告诉我,希望这对您有所帮助。谢谢!


hl0*_*37_ 4

嗯……这个问题让我非常恼火,以至于我编写了一个模块来处理所有这些复杂的情况。人们可以在这里找到它: https: //github.com/hl037/vue-data-proxy

然后,我们可以简单地编写这种组件:

import vueDataProxy from "vue-data-proxy";

export default {
  props : {
    user_ind;
  }
  computed : {
    ...vueDataProxy({
      user : {
        fetch() {
          return this.$store.state.foo.bar.users[this.user_ind];
        },
        commit(val){
          // here, val is the full object (if reactivity injected)
          // returned by fetch
          this.$store.commit('updateUser', {ind : this.user_ind, val}
        }
     }
  },
  //...
}
Run Code Online (Sandbox Code Playgroud)

...假设你有一种突变称为updateUser(state, {ind, val}) { /*...*/ }

...然后,它将提交任意深度的每个修改