【问题标题】:Can you use v-model to add / remove elements from an array?您可以使用 v-model 从数组中添加/删除元素吗?
【发布时间】:2020-12-03 21:24:01
【问题描述】:

我是 Vue.js 的新手,并试图改掉良好的老式 vanilla DOM 操作的习惯。我决定重新创建一种动态表单,其中您可以添加一定数量的表单控件(在本例中为文本输入)基于用户输入

假设您必须指定您拥有的孩子的数量。将为每个孩子呈现名字和姓氏文本字段。

您可以使用 input[type="number"] 或手动来更改孩子的数量。

依赖:
vue@2

这是我的 HTML:

<div id="app">
  <form>
      <label for="childrenCount">Amount of children</label>

      <input
        type="number"
        id="childrenCount"
        min="0"
        v-model="amountOfChildren"
      />

    <template v-if="amountOfChildren > 0">
      <h2>Children</h2>

      <div
        v-for="(child, index) in children"
        :key="index">

        Child {{ index + 1 }}:

        <input
          type="text"
          placeholder="First name"
          v-model="child.firstName"
        />

        <input
          type="text"
          placeholder="Last name"
          v-model="child.lastName"
        />
      </div>
    </template>
  </form>
</div>

这是我的 Vue 代码:

<script>
  new Vue({
    el: '#app',

    data() {
      return {
        amountOfChildren: 0,

        form: {
          children: []
        }
      }
    },

    computed: {
      children() {
        this.form.children = [];

        for (let index = 0; index < this.amountOfChildren; index++)
          this.form.children.push({ firstName: '', lastName: '' });

        return this.form.children;
      }
    }
  });
</script>

有了这个,如果我增加/减少孩子的数量,我会失去所有的变化(因为计算属性)。 有没有办法只使用 v-model 来实现我的目标?没有按钮和发射事件?

我尝试使用观察者和自定义方法但没有运气...

预期的数据结构:

form: {
  "children": [
      { "firstName": "Jinny", "lastName": "Doe" },
      { "firstName": "James": "lastName": "Doe" }
  ]
}

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    您可以将children 重构为一个方法,并改用@input 事件处理程序:

    new Vue({
      el: '#app',
    
      data() {
        return {
          form: {
            children: []
          }
        }
      },
    
      methods: {
        children(e) {
          const {
            children
          } = this.form;
          const popOrPush = e.target.value > children.length ? 'push' : 'pop';
          const difference = Math.abs(e.target.value - children.length);
    
          for (let i = 0; i < difference; i++) {
            this.form.children[popOrPush]({
              firstName: '',
              lastName: ''
            });
          }
        }
      }
    });
    
    Vue.config.productionTip = false;
    Vue.config.devtools = false;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <form>
        <label for="childrenCount">Amount of children</label>
    
        <input type="number" id="childrenCount" min="0" @input="children" />
    
        <template v-if="form.children.length > 0">
          <h2>Children</h2>
    
          <div
            v-for="(child, index) in form.children"
            :key="index">
    
            Child {{ index + 1 }}:
    
            <input
              type="text"
              placeholder="First name"
              v-model="child.firstName"
            />
    
            <input
              type="text"
              placeholder="Last name"
              v-model="child.lastName"
            />
          </div>
        </template>
      </form>
    </div>

    编辑

    显然我太累了,无法正确阅读您的问题,即

    有没有办法只使用 v-model 来实现我的目标?没有按钮和发射事件?

    不过,我还是把它留在这里,以防你觉得它有用。

    【讨论】:

    • 我刚刚注意到您的代码中有一个小错误。阅读 OP 问题:“您可以使用 input[type="number"] 或手动更改孩子的数量。”如果你输入让我们说5怎么办?仍然只有 1 对输入。
    • 啊,好地方。您可以计算差异,将其转换为正数 (Math.abs),然后使用循环推送/弹出每个孩子,请参阅我的编辑
    猜你喜欢
    • 2017-01-30
    • 2010-10-10
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2018-10-17
    相关资源
    最近更新 更多