Vuex嵌套循环,如何在select / option上处理v-model

时间:2017-01-28 21:43:31

标签: vue.js vuex

在我的应用程序中,我需要使用嵌套的v-for来显示带有select-option的元素列表。这是场景

<div class="stuck" v-for="box in items">
  <p>Pick an option for this box:</p>
  <select v-model="box">
      <option v-for="package in packages" 
              :value="package.id">{{ package.name }} </option>
  </select>
</div>

变量项来自Vuex商店。通过这种方式,我得到了错误:

  

您将v-model直接绑定到v-for迭代别名。这将   无法修改v-for源数组因为写入   别名就像修改函数局部变量一样。考虑使用   对象数组,而是在对象属性上使用v-model。

考虑到这一点,我将改变代码:

<div class="stuck" v-for="box in items">
  <p>Pick an option for this box:</p>
  <select v-model="box.id">
      <option v-for="package in packages" 
              :value="package.id">{{ package.name }} </option>
  </select>
</div>

我刚刚将选择v-model从别名更改为正确的ID: box.id

通过这种方式,所有作品 ......或......一半有效。因为,如果我要从选择中选择一个选项,我会收到另一个错误:

  

[vuex]不要在变异处理程序之外改变vuex存储状态。

这是正确的,因为v-model绑定到 box.id (这不是别名,而是实际值)。 但是,当我选择一个选项 v-model&#34;尝试&#34;更改来自 Vuex商店 box.id

现在,在一个简单的场景中,我将为set / get创建一个计算属性,以避免vuex存储突变。

但是......这里我有一个嵌套循环,所以我无法在&#39; box.id&#39; 上创建计算。

你有解决方案吗?

非常感谢!

2 个答案:

答案 0 :(得分:0)

您可以尝试不同的数据流模式。 您的选择会侦听商店(但不会直接更新)

<div class="stuck" v-for="box in items">
  <p>Pick an option for this box:</p>
  <select :value="box.id" @change="updateBox">
    <option v-for="package in packages" :value="package.id">
      {{ package.name }}
    </option>
  </select>
</div>

然后创建一个方法,只要所选选项发生变化就会触发

updateBox(e) {
  const id = e.target.value;
  this.$store.commit('changeYourBox', id);
},

此函数应提交更改box id的vuex变异。所以你也需要这种突变。 商店值更新后,您的组件box对象更新,并且侦听该商店的选择将相应地更新其选定的值。

这样,您可以从任何地方更改商店价值,所选值也会改变。

答案 1 :(得分:0)

使用我的库 vuex-dot ,在这种情况下你可以这样做:

让我们选择这样的状态

  {
    state: {
      boxes: []
    },
    mutations: {
      editBox(state, {target, key, value}) {
        Vue.set(target, key, value);
      }
    }
  };

因此,让我们创建额外的组件BoxEdit:

<template>
  <div class="stuck">
    <p>Pick an option for this box:</p>
    <select v-model="id">
      <option v-for="package in packages"
              :value="package.id">{{ package.name }} </option>
    </select>
  </div>
</template>

<script>
  import { take } from 'vuex-dot'
  export default {
    props: ['box', 'packages'],
    computed: {
      ...take('box')
        .expose(['id'])
        .commit('editBox', true)
        .map()
    }
  }
</script>

现在你可以简单地写

<box-edit v-for="box in boxes" :box="box" :packages="packages"></box-edit>

在主题组件模板中。

指向图书馆网站的链接:https://github.com/yarsky-tgz/vuex-dot