2017-09-05 106 views
0

我問的問題關於添加/在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> 

回答

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>

具體而言,要共享數據的方式是因爲你定義像這樣的數據:

變種DATA1 = {選自:空,項目:[ 「A1」, 「B1」]};

並返回從數據函數對象的組件:

data:function(){ 
    return data1 
}   

這意味着該組件的每個實例共享相同數據。這不是你想要的組件。每個組件都應該有自己的數據副本。在這種情況下,不需要定義從數據功能返回的數據對象以外的組件。

+0

伯特,非常感謝這樣詳細的解釋和演示!因爲我是vue.js的新手,所以從組件外部傳遞數據的原因是我希望能夠有更好的方式將此選擇組件作爲模板使用,因爲這些組件的唯一區別是不同的選擇列表。 – user1830108

+0

@ user1830108通常,當您想要自定義組件時,您會以道具形式傳遞數據。在這種情況下,您可以將選項作爲道具傳入。 – Bert