javascript - 如何在 Vue.js 中创建独立运行的动态行?

标签 javascript vue.js dynamic row html-select

我有一个创建动态行的 vue 实例。该行有两个选择选项: PersonInterests 以及 Add row 按钮。这些选择选项是依赖选项:

enter image description here

如果我选择 Brian 作为,他在第二个选择选项中的兴趣应该加载 Brian 的兴趣。这效果很好:

enter image description here

问题:

这工作正常,但是我无法克服的奇怪的事情是当添加第二行时,第二行删除布莱恩的兴趣并填充第二个人的兴趣:

enter image description here

例如,Brian 对 Crossfit 不感兴趣 - 这些是 Candice 的选择。本质上,Brian 的选项不会被保留,它们会被 Candices 覆盖 - 因此两行都显示 Candices 的兴趣。

任何人都可以建议我需要做什么来解决这个问题吗?我创建了一个 Jsfiddle 来说明这个问题:

https://jsfiddle.net/syed263/y9emdLvr/45/

HTML:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
  </head>

  <body>
    <div id="app">
      <ul>
        <li v-for="(input, index) in inputs">
          Person:
          <select type="text" v-model="input.one" v-on:change="updateList(input.one)">  
             <option v-for= "options in person._person" v-bind:value ="options">
                {{ options.name }}
             </option>
          </select> Interests:
          <select type="text" v-model="input.two"> 
             <option v-for= "options in activity._activity" v-bind:value ="options">
                {{ options.name }}
             </option>
          </select>
          <button @click="deleteRow(index)">Delete</button>
        </li>
      </ul>

      <button @click="addRow">Add row</button>

    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>

  </body>

</html>

JS:声明

let _people = {

  _person: [{
      name: 'Adam',
      age: '16',
      ID: '2009121',

    },
    {
      name: 'Brian',
      age: '18',
      ID: '2009122',

    },
    {
      name: 'Candice',
      age: '16',
      ID: '2009120',

    },
  ]
}

let _interests = {

  _activity: [{
    name: '',
    type: '',

  }, ]
}

let person

JS 方法:

const app = new Vue({

  el: '#app',

  data: {
    inputs: [],
    person: _people,
    activity: _interests,
  },

  methods: {
    addRow() {
      this.inputs.push({
        one: '',
        two: ''
      })
    },
    deleteRow(index) {
      this.inputs.splice(index, 1)
    },
    updateList(val) {
      this.activity._activity = [];

      if (val.name == "Adam") {
        this.activity._activity.push({
          name: 'Badminton',
          type: '20'
        }, {
          name: 'Football',
          type: '30'
        })
      } else if (val.name == "Brian") {
        this.activity._activity.push({
          name: 'Basketball',
          type: '90'
        }, {
          name: 'Karate',
          type: '50'
        })
      } else if (val.name == "Candice") {
        this.activity._activity.push({
          name: 'Climbing',
          type: '90'
        }, {
          name: 'Cross Fit',
          type: '100'
        })
      }

    }
  }

})

JSfiddle:https://jsfiddle.net/syed263/y9emdLvr/45/

最佳答案

问题是您使用 this.activity._activity (每行都使用相同的)生成 <option>
但在 updateList()每当第一个选择值发生变化时,无论哪一行, 它会改变this.activity._activity .
它将影响每一行的所有第二个选择选项。
所以你应该做一些事情来链接 activity到每一行。 示例代码如下所示,它可以工作,但并不完美。

let _people = {

  _person: [{
      name: 'Adam',
      age: '16',
      ID: '2009121',

    },
    {
      name: 'Brian',
      age: '18',
      ID: '2009122',

    },
    {
      name: 'Candice',
      age: '16',
      ID: '2009120',

    },
  ]
}

let _interests = {

  _activity: [{
    name: '',
    type: '',

  }, ]
}

let person


const app = new Vue({

  el: '#app',

  data: {
    inputs: [],
    person: _people,
    activity: _interests,
  },

  methods: {
    addRow() {
      this.inputs.push({
        one: '',
        two: '',
        activity: [] // To link activity with each row
      })
    },
    deleteRow(index) {
      this.inputs.splice(index, 1)
    },
    updateList(val, index) {
      this.activity._activity = [];

      if (val.name == "Adam") {
        // only change current row's second option
        this.inputs[index].activity =[{
          name: 'Badminton',
          type: '20'
        }, {
          name: 'Football',
          type: '30'
        }]
      } else if (val.name == "Brian") {
        this.inputs[index].activity =[{
          name: 'Basketball',
          type: '90'
        }, {
          name: 'Karate',
          type: '50'
        }]
      } else if (val.name == "Candice") {
        this.inputs[index].activity =[{
          name: 'Climbing',
          type: '90'
        }, {
          name: 'Cross Fit',
          type: '100'
        }]
      }

    }
  }

})
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
  </head>

  <body>

    <div id="app">

      <ul>
        <li v-for="(input, index) in inputs">
          Person:
          <select type="text" v-model="input.one" v-on:change="updateList(input.one, index)">  
						<option v-for= "options in person._person" v-bind:value ="options">
						{{ options.name }}
					 </option>
				
				</select> Interests:
          <select type="text" v-model="input.two"> 
						<option v-for= "options in input.activity" v-bind:value ="options">
						{{ options.name }}
					 </option>
								
					</select>
          <button @click="deleteRow(index)">Delete</button>
        </li>
      </ul>

      <button @click="addRow">Add row</button>

    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>

  </body>

</html>

关于javascript - 如何在 Vue.js 中创建独立运行的动态行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51853666/

相关文章:

vue.js - 如何在 bootstrap-vue 中为 b-form-checkbox-group 设置所需的验证?

html - YouTube 嵌入动态大小与最小和最大大小

c# - Linq to Objects 按任意数量的参数排序

javascript - 上传前的 jQuery 图像预览脚本

javascript - 用 mocha 测试 ember js?

javascript - 在 AngularJS 中从数组中获取对象的正确方法

ruby-on-rails - Rails + Vue.js - 使用 Ajax 更新 Vue 组件

javascript - MUI 中的 <Div>、<StyledDiv> 和 <Box sx={...}> 之间有什么区别?

css - 构建产品不显示字体 - 基本的 webpack init

javascript - 使用 jquery 删除输入后无法重新计算动态添加输入的总和?