如何使用动态路径作为突变的有效负载从Vuex存储中删除条目?

时间:2019-04-09 20:28:59

标签: javascript vue.js vuex vue-reactivity

我想为vuex状态创建一个变异,但要使其动态更新状态-使有效负载包含要删除其元素的对象和键的路径。

  1. 调度动作
deleteOption(path, key) 
{ this.$store.dispatch('deleteOptionAction', {path, key}) }
  1. 进行突变
deleteOptionAction ({ commit }, payload) { commit('deleteOption', payload) }
  1. 该变异接收路径为'state.xmlValues.Offers [0] .data.Pars'并且键= 0的有效载荷
deleteOption (state, payload) { 
  let stt = eval('state.' + payload.path)
  Vue.delete(stt, payload.key)
  // delete stt[payload.key] - works the same as Vue.delete
  state.xmlValues.Offers[0].data.Pars = Object.assign({}, Object.values(stt))
   }

我尝试使用state [payload.path]语法-但这不起作用。 该路径包括字符串'state.xmlValues.Offers [0] .data.Pars',因此为了使其正常工作,我使用了let stt = eval('state。'+ payload.path)。 但是,从状态中删除一个元素变得棘手: 使用Vue.delete(stt,payload.key)时-只会删除本地存储在stt变量中的元素键,而不会删除状态。

然后,我用stt(已经从中删除了所需元素的状态)重新分配了状态对象,并对路径进行了硬编码-这就是我要避免的事情:

state.xmlValues.Offers[0].data.Pars = Object.assign({}, Object.values(stt))

如何传递路径到商店,然后使用它删除状态下的对象,而无需明确地对路径进行硬编码?

至于我的其他变异addOption,我也使用了指向状态对象的动态路径-当使用stt中评估的动态路径时,它工作得很好

addOption (state, payload) {
      let stt = eval('state.' + payload.path)
      Vue.set(stt, payload.key, payload.newEl)
   }

2 个答案:

答案 0 :(得分:1)

首先,请不要使用eval(..)。曾经此功能允许任意代码执行,您不执行任何操作以清除值!

一个更明智的选择是自己解析路径。您可以自己写点东西,但是lodash已经具有toPath功能。它返回一个数组,其中包含我们尝试获取的每个部分。

现在我们知道如何获取要删除的键,我们可以编写一些代码来测试每个部分是否存在以及每个部分是对象还是数组。但是,由于我们现在正在使用lodash,因此可以使用_.get_.isObjectLike来简化生活:

import { toPath, get, isObjectLike } from 'lodash-es';

function deletePath(source, pathStr) {
    const path = toPath(pathStr);

    const selector = path.slice(0, -1);
    const key = path[path.length - 1];

    let deletableSource = source;

    if (selector.length && isObjectLike(source)) {
      deletableSource = get(source, selector);
    }

    if (isObjectLike(deletableSource)) {
      // We can delete something from this!
      this.$delete(deletableSource, key);
    }
}

现在有了它,我们可以做一些事情,例如将其分配给Vue原型,或者将其作为辅助函数导出到某个地方。我将重写您的addOption作为读者的练习。

Edit How to delete entries from Vuex store using dynamic path as payload for a mutation?

答案 1 :(得分:0)

由于@ Sumurai8,我发现可以像这样传递参数而不是字符串,实际上是对商店的引用。因此, 无需将状态信息传递给状态中的对象

<button @click="deleteOption($store.state.xmlValues.Offers[mainData.curOfferKey].data.Pars)">delete</button>

lodash的 get toPath 功能也非常有用!