【问题标题】:issue caused the Row selection overwrite问题导致行选择覆盖
【发布时间】:2017-09-05 18:07:54
【问题描述】:

我问了关于在how to use "v-for" for adding or removing a row with multiple components 中添加/删除行的问题

但是,我遇到了一个错误:当我添加一行时,第一行中的项目填充到第二行,当我更改第二行时,第一行也被覆盖,与第二行相同。

我一定做错了。

在.js中

 var data1={selected: null, items: ["A1","B1"]};
 Vue.component('comp1',{
       template: ` <select v-model="selected">
           <option disabled value="">Please select</option>
           <option v-for="item  in items" :value="item">{{item}}
            </option>
           </select>`,
      data:function(){
         return data1
         }         
     });

    var data2={selected: null, items: ["A2","B2"]};
    Vue.component('comp2',{
        template: ` <select v-model="selected">
                     <option disabled value="">Please select</option>
                     <option v-for="item in items" :value="item">{{item}}
            </option>
             </select>`,
           data:function(){
           return data2
            }          
          });




new Vue({
  el: '#app',
  data: {
    rows: []
  },
  computed:{
    newId(){
     return this.rows.length == 0 ? 1 : Math.max(...this.rows.map(r => r.id)) + 1
    }
  },
  methods: {
    addRow: function() {
      this.rows.push({id: this.newId });
    },
    removeRow: function(row) {
       this.rows.splice(this.rows.indexOf(row), 1)
    }
  },

});

在.html中

<div id="app">
  <div v-for="row in rows">
    <comp1></comp1>
    <comp2></comp2>

    <button @click="removeRow(row)">Remove Row</button>
  </div>
  <button @click="addRow">Add Row</button>
</div>

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    您需要添加密钥。

    <div v-for="row in rows" :key="row.id">
    

    而且你不应该在组件之间共享数据,所以将你的数据移动到组件中。

    data: function() {
      return {
        selected: null,
        items: ["A1", "B1"]
      }
    }
    

    这是一个工作版本。

    Vue.component('comp1', {
      template: ` <select v-model="selected">
               <option disabled value="">Please select</option>
               <option v-for="item  in items" :value="item">{{item}}
                </option>
               </select>`,
      data: function() {
        return {
          selected: null,
          items: ["A1", "B1"]
        }
      }
    });
    
    Vue.component('comp2', {
      template: ` <select v-model="selected">
                         <option disabled value="">Please select</option>
                         <option v-for="item in items" :value="item">{{item}}
                </option>
                 </select>`,
      data: function() {
        return {
          selected: null,
          items: ["A2", "B2"]
        }
      }
    });
    
    
    
    
    new Vue({
      el: '#app',
      data: {
        rows: []
      },
      computed: {
        newId() {
          return this.rows.length == 0 ? 1 : Math.max(...this.rows.map(r => r.id)) + 1
        }
      },
      methods: {
        addRow: function() {
          this.rows.push({
            id: this.newId
          });
        },
        removeRow: function(row) {
          this.rows.splice(this.rows.indexOf(row), 1)
        }
      },
    
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
    <div id="app">
      <div v-for="row in rows" :key="row.id">
        <comp1></comp1>
        <comp2></comp2>
    
        <button @click="removeRow(row)">Remove Row</button>
      </div>
      <button @click="addRow">Add Row</button>
    </div>

    具体来说,您共享数据的方式是因为您是这样定义数据的:

    var data1={selected: null, items: ["A1","B1"]};

    并从组件中的数据函数返回该对象:

    data:function(){
      return data1
    }         
    

    这意味着该组件的每个实例都在共享相同的数据。这不是您想要的组件。每个组件都应该有自己的数据副本。在这种情况下,无需在组件外部定义从数据函数返回的数据对象。

    【讨论】:

    • Bert,非常感谢您提供如此详细的解释和演示!!!由于我是 vue.js 的新手,从组件外部传递数据的原因是我希望有更好的方法将此选择组件用作模板,因为此类组件的唯一区别是不同的选择列表。跨度>
    • @user1830108 通常,当您想要自定义组件时,您会将数据作为道具传递。在这种情况下,您可以将选项作为道具传递。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 2011-08-21
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    相关资源
    最近更新 更多