【问题标题】:Vuex nested loop, how to handle v-model on select/optionVuex嵌套循环,如何在选择/选项上处理v-model
【发布时间】:2017-06-14 09:15:39
【问题描述】:

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

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

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

这样,所有的工作...或...一半的工作。因为,如果我要从选择中选择一个选项,我会遇到另一个错误:

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

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

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

但是...这里我有一个嵌套循环,所以 我不能在 'box.id' 上创建一个计算对象

你有解决办法吗?

非常感谢!

【问题讨论】:

  • :value="box.id" @input="$store.commit('boxUpdated', { id: box.id, value: $event.target.value })" 或类似的东西替换v-model,不确定语法但我会这样做
  • 您可以考虑使用&lt;select&gt; 元素修改box.id 以外的某些属性。另一位开发人员可能期望box.id 能够可靠地区分boxes,但它实际上记住了用户的package 选择。如果您使用box.selected_package_id 而不是box.id 会怎样?

标签: vue.js vuex


【解决方案1】:

您可以尝试不同的数据流模式。 你的 select 监听 store(但不直接更新它)

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

这个函数应该提交一个改变盒子 id 的 vuex 突变。所以你也需要那个突变。 一旦存储值更新,您的组件box 对象就会更新,并且侦听该存储的选择将相应地更新其选定值。

这样,您可以从任何地方更改存储值,并且所选值也会更改。

【讨论】:

    【解决方案2】:

    在这种情况下使用我的库 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

    【讨论】:

      猜你喜欢
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      • 2012-11-01
      相关资源
      最近更新 更多