【问题标题】:How to append multi row in vuejs如何在 vuejs 中追加多行
【发布时间】:2020-05-06 06:57:14
【问题描述】:

我的要求是在我的表单中制作嵌套数据,并且每个数据都能够添加更多行或删除它们。我以前用 JavaScript 做过这样的事情,但是用 VueJs 这是我的第一次尝试,所以我有点需要推动 :)

逻辑

  1. 父数据有选择选项,让用户选择什么 他们需要的输入类型,并根据该选择附加 输入。 (红色)
  2. 可以添加或删除我的父数据,这样我就可以拥有多个父数据 并且他们每个人同时有几个孩子(蓝色)
  3. 可以添加或删除我的孩子数据(绿色)

代码

这是我的第一个静态 html(还没有为它编写脚本)

Ps:所有部分都有注释。

<el-form-item label="Variation Name">
    <el-col :span="12">

        // parent
        <el-input placeholder="Please input your variation name" v-model="form.variationParent" class="input-with-select">
            // select type of child's input
            <el-select v-model="form.variationParent" slot="prepend" placeholder="Select">
                <el-option label="Text" value="1"></el-option>
                <el-option label="Text Area" value="2"></el-option>
                <el-option label="Boolean" value="3"></el-option>
            </el-select>
            <el-button slot="append" type="success" icon="el-icon-plus"></el-button> //add parent
            <el-button slot="append" type="danger" icon="el-icon-delete"></el-button> // delete parent
        </el-input>

    </el-col>

    <el-col class="line text-center" :span="3">Variation Value(s)</el-col>
    <el-col :span="9">

        // child's
        <el-input v-model="form.variationChilds" placeholder="Please input your variation value" class="input-with-select">
            <el-button slot="append" type="success" icon="el-icon-plus"></el-button> //add child
            <el-button slot="append" type="danger" icon="el-icon-delete"></el-button> // delete child
        </el-input>

    </el-col>
</el-form-item>

感谢任何形式的ideasample codes

更新

我已经设法使用此代码添加和删除父部分:

<el-form-item v-for="(index, k) in variationParents" :key="k" label="Variation Name">
    <el-col :span="12">

        <!-- parent -->
        <el-input placeholder="Please input your variation name" v-model="form.variationParent" class="input-with-select">
            <el-select v-model="form.variationParent" slot="prepend" placeholder="Select">
                <el-option label="Text" value="input"></el-option>
                <el-option label="Text Area" value="textarea"></el-option>
                <el-option label="Boolean" value="boolean"></el-option>
            </el-select>
            <el-button slot="append" @click="add(k)" type="success" icon="el-icon-plus"></el-button>
            <el-button slot="append" @click="remove(k)" v-show="k || ( !k == variationParents.lenghth > 1)" type="danger" icon="el-icon-delete"></el-button>
        </el-input>

    </el-col>

    <el-col class="line text-center" :span="3">Variation Value(s)</el-col>
    <el-col :span="9">

        <!-- child's -->
        <el-input v-model="form.variationChilds" placeholder="Please input your variation value" class="input-with-select">
            <el-button slot="append" type="success" icon="el-icon-plus"></el-button>
            <el-button slot="append" type="danger" icon="el-icon-delete"></el-button>
        </el-input>

    </el-col>
</el-form-item>

data() {
    return {
        variationParents: [
            {
                name: '',
                type: ''
            }
        ],
    }
},
methods: {
    add(index){
        this.variationParents.push({name: '', type: ''});
    },
    remove(index){
        this.variationParents.splice(index, 1);
    },
}

这是结果+问题

如您所见,我有新的父母行和add / remove 按钮在工作,但我的输入都得到相同的值,这意味着如果我将第一个输入设置为所有的东西都会得到相同的值。

它们需要每个具有不同的值并作为数组发送到后端。

【问题讨论】:

  • @YomS。关于这个问题,我所拥有的只是我包含在问题中的 html 部分,但如果你需要我可以制作 jsfiddle,但我拥有的所有代码都是这样的 :)
  • 嗯,这个小提琴看起来完全不同,与您的模板无关。请发布一些您迄今为止尝试过的数据或脚本。
  • 您获得共享值的原因是因为您在不同的对象 (form) 上执行 v-model,而不是在 v-for 中循环的内容。

标签: javascript vue.js element-ui


【解决方案1】:

我实际上无法运行您的 jsfiddle,但是查看您的代码,我认为您已经非常接近了,只是,正如我在评论中所说,您需要将这些输入/表单元素绑定到单个 variationParents 上与v-for 循环。

这里有一些简单的示例,展示了如何在组件之间同步这些父值。不过,我无法为您添加所有内容。

此外,随着您的扩展,您可能需要考虑使用 Vuex 来更好地管理状态。

const variationNames = ['Text', 'Text Area', 'Boolean'];

const VariationBar = Vue.extend({
  template: '#variation-bar',
  props: {
    name: {
      type: String,
      // This simply ensures that the `name` property 
      // be validated against the list, while binding;
      // https://vuejs.org/v2/guide/components-props.html#Prop-Validation
      validator: val => variationNames.includes(val)
    },
    values: {
      type: Array
    }
  },

  data: () => ({
    variationNames
  }),

  computed: {
    // Read more here on how computed setter works:
    // https://vuejs.org/v2/guide/computed.html#Computed-Setter
    inputName: {
      get() {
        return this.name;
      },
      set(val) {
        // When setter gets invoked, emit the new value
        // and notify the parent that it needs to "sync" it.
        // This works hand-in-hand with the `.sync` modifier
        // https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier
        this.$emit('update:name', val);
      }
    }
  },
  
  methods: {
    addValue() {
      // Add your default item/preset here
      this.values.push({
        text: ''
      })
    },
    removeValue(index) {
      this.values.splice(index, 1);
    }
  }
})

new Vue({
  el: '#app',

  data: vm => ({
    variations: [{
      name: 'Boolean',
      values: [
        { text: 'Core i3' },
        { text: 'Core i5' }
      ]
    }]
  }),

  methods: {
    addVariation() {
      this.variations.push({
        name: 'Text',
        values: [
          { text: 'Core i3' }
        ]
      });
    },
  },

  components: {
    VariationBar
  }
})
.variation {
  display: flex;
  justify-content: space-between;
  margin-bottom: 2rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <variation-bar v-for="item of variations" :key="item.name" :name.sync="item.name" :values="item.values" @variation:add="addVariation">
  </variation-bar>
  
  <pre>{{variations}}</pre>
</div>

<template id="variation-bar">
  <div class="variation">
    <div class="variation__col">
      <label>Variation Name</label>
      <select v-model="inputName">
        <option
          v-for="name of variationNames" :key="name"
          :value="name"
          v-text="name">
        </option>
      </select>

      <div class="variation__btn-group">
        <button @click="$emit('variation:add')">add</button>
        <button @click="$emit('variation:remove')">remove</button>
      </div>
    </div>

    <div class="variation__col">
      <label>Variation values(s)</label>

      <div
        v-for="(val, index) of values" :key="`${val.text}-${index}`"
        class="variation__value">
        <input type="text" v-model.lazy="val.text" />

        <div class="variation__btn-group">
          <button @click="addValue">add</button>
          <button @click="removeValue(index)">remove</button>
        </div>
      </div>
    </div>
  </div>
</template>

【讨论】:

  • 感谢您的回答,您介意评论每个部分,以便我了解放置它们的位置或每个部分的作用吗?例如,现在我放置那些const 的任何地方都破坏了其他部分。 ://
  • 你的意思是我的例子中的variationNames const 吗?你在哪里以及如何使用它?这实际上仅用于道具检查。
  • 我在示例中添加了一些内联 cmets。如果您可以让 jsfiddle 正常工作并且问题可重现,我实际上可以帮助您处理真正的代码(您有问题的应用程序)。就目前而言,我什至无法运行它。小提琴上缺少太多信息。但这取决于你。
  • 谢谢,如果我给你我的组件怎么办?这对你有帮助吗?我只是发给你完整的组件?
  • 这是我的完整组件collabedit.com/ywheq,我评论了问题部分,以便您轻松找到它
猜你喜欢
  • 1970-01-01
  • 2014-10-23
  • 2012-05-10
  • 2017-07-17
  • 2023-01-04
  • 1970-01-01
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多