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

时间:2018-08-03 12:18:57

标签: vuejs2 vuex

Vuex非常适合显示复杂的数据,并且可以进行复杂的变异(例如,在整个商店中向节点添加具有影响的树等),但是,对我来说,处理“简单”变异。

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

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

目前,这是我要做的: 在显示/编辑对象的组件中,我在组件的data中放置了可以编辑的对象的“骨架”(一个具有所有嵌套属性的对象,但所有叶子均设置为null )。然后,当模式打开或组件应显示/使对象可编辑时,我只需将对象深层复制(使用递归函数)复制到data,然后用{{1}观看数据}选项deep,并在每次更改时提交。

这感觉有点不对劲,需要付出很大的努力才能使其生效。

我喜欢突变可追溯性系统,我希望每次对嵌套属性进行修改时都提交整个对象。如果不编写大量代码就可以做到这一点真的很棒(我想知道,简单地放弃一个简单的全球Vue Componnent商店的vuex并折衷于好的变异系统是否值得?简单的代码)

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

存储状态示例:

true

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

3 个答案:

答案 0 :(得分:0)

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

{
  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')
   }
 }

}

希望有帮助!

答案 1 :(得分:0)

我建议以这种方式使用:

  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>

VUEX

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)
    }
  }

}

让我知道是否有不清楚的地方,希望对您有所帮助。 谢谢!

答案 2 :(得分:0)

嗯...这个问题使我非常恼火,以至于我编写了一个模块来处理所有这些复杂的情况。可以在这里找到它: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}
        }
     }
  },
  //...
}

...假设您有一个名为updateUser(state, {ind, val}) { /*...*/ }的突变

...然后,它将在任何深度进行每次修改