javascript - 如何在vuejs中追加多行

标签 javascript vue.js element-ui

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

逻辑

one

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

代码

这是我的第一个静态 html(尚未为其编写脚本)

Ps: all parts are commented.

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

任何类型的想法示例代码都值得赞赏。

更新

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

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

这是结果+问题

three

如您所见,我有新的父行和添加/删除按钮正在工作,但我的输入都获得相同的值,这意味着如果我将第一个输入设置为某些内容,那么所有输入都将获得相同的值。

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

最佳答案

我实际上无法运行你的jsfiddle,但是看看你的代码,我认为你已经非常接近了,只是,正如我在评论中所说,你需要将这些输入/表单元素绑定(bind)在各个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>

关于javascript - 如何在vuejs中追加多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59820358/

相关文章:

javascript - 选择菜单 ('refresh',正确)

javascript - 如何使用 vue.js 显示格式化的 html 字符串

vue.js - 如何在 Element UI 表格行中正确设置链接(应该很简单?)

javascript - 了解 Element UI 事件处理程序触发 RangeError : Maximum call stack size exceeded? 的原因

javascript - 如何验证 dojo OnDemandGrid 中的编辑器字段

javascript - 在不重新加载页面的情况下更改图像 src

javascript - koa-router错误router.routes不是一个函数

vue.js - Vue Devtools 在本地不工作

javascript - 仅当 json 响应为 true 时才启用下一个按钮(转到另一个选项卡)?