【问题标题】:How to delete entries from Vuex store using dynamic path as payload for a mutation?如何使用动态路径作为突变的有效负载从 Vuex 存储中删除条目?
【发布时间】:2019-08-31 05:18:42
【问题描述】:

我想为 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' 和 key = 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)
   }

【问题讨论】:

    标签: javascript vue.js vuex vue-reactivity


    【解决方案1】:

    感谢@Sumurai8,我发现可以像这样传递参数,而不是字符串,而是对商店的引用。所以 不需要传递 sting 与状态中的对象的路径。

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

    lodash gettoPath 函数也非常有用!

    【讨论】:

      【解决方案2】:

      第一件事:不要使用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 作为读者练习。

      【讨论】:

        猜你喜欢
        • 2020-03-22
        • 2021-09-08
        • 2022-01-17
        • 2021-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-19
        相关资源
        最近更新 更多