2016-11-27 63 views
0

對於我的應用程序,我使用了兩個Vue組件。一個呈現「天」的列表,一個呈現每個「日」的「位置」列表。因此,例如「第一天」可以具有「柏林」,「倫敦」,「紐約」的位置。vue2 v-for嵌套組件道具在父元素被刪除後不會更新

所有內容都呈現正常,但從視圖未被修正的天數列表中刪除「第1天」後。這是發生了什麼:

  1. 被刪除被替換一天的標題 ​​- >正確
  2. 被刪除未替換一天的內容 - >不正確

Vue.component('day-list', { 
 
    props: ['days'], 
 
    template: '<div><div v-for="(day, index) in dayItems">{{ day.name }} <a href="#" @click.prevent="remove(index)">Remove day</a><location-list :locations="day.locations"></location-list><br/></div></div>', 
 
    data: function() { 
 
    return { 
 
     dayItems: this.days 
 
    } 
 
    }, 
 
    methods: { 
 
    remove(index) { 
 
     this.dayItems.splice(index, 1); 
 
    } 
 
    } 
 
}); 
 

 
Vue.component('location-list', { 
 
    props: ['locations', 'services'], 
 
    template: '<div><div v-for="(location, index) in locationItems">{{ location.name }} <a href="#" @click.prevent="remove(index)"</div></div>', 
 
    data: function() { 
 
    return { 
 
     locationItems: this.locations 
 
    } 
 
    }, 
 
    methods: { 
 
    remove(index) { 
 
     this.locationItems.splice(index, 1); 
 
    } 
 
    } 
 
}); 
 

 
const app = window.app = new Vue({ 
 
    el: '#app', 
 

 
    data: function() { 
 
    \t return { 
 
    \t days: [ 
 
     { 
 
      name: 'Day 1', 
 
      locations: [ 
 
      {name: 'Berlin'}, 
 
      {name: 'London'}, 
 
      {name: 'New York'} 
 
      ] 
 
     }, 
 
     { 
 
      name: 'Day 2', 
 
      locations: [ 
 
      {name: 'Moscow'}, 
 
      {name: 'Seul'}, 
 
      {name: 'Paris'} 
 
      ] 
 
     } 
 
     ] 
 
    } 
 
    }, 
 

 
    methods: {} 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script> 
 

 

 
<div id="app"> 
 
    <day-list :days="days"></day-list> 
 
</div>

回答

0

如果你尚未使用請使用Vue-devtools。它顯示了清楚的問題,因爲看到如下圖所示:

Screenshot from Vue devtools

正如你可以在上面看到,你day-list組分包含所有你必須在原來的列表中,用了直接上市地點天。您需要在中間再添加一個組件,將其稱爲day-details,這將呈現特定日期的信息。您可能在day-details內有location-list

這裏是更新的代碼工作:

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

<div id="app"> 
    <day-list :days="days"></day-list> 
</div> 
Vue.component('day-list', { 
    props: ['days'], 
    template: ` 
     <div> 
      <day-details :day="day" v-for="(day, index) in days"> 
       <a href="#" @click.prevent="remove(index)">Remove day</a> 
      </day-details> 
     </div>`, 
    methods: { 
     remove(index) { 
      this.days.splice(index, 1); 
     } 
    } 
}); 

Vue.component('day-details', { 
    props: ['day'], 
    template: ` 
     <div> 
      {{ day.name }} 
      <slot></slot> 
      <location-list :locations="day.locations"></location-list> 
      <br/> 
     </div>` 
}); 

Vue.component('location-list', { 
    props: ['locations', 'services'], 
    template: ` 
     <div> 
      <div v-for="(location, index) in locations"> 
       {{ location.name }} 
       <a href="#" @click.prevent="remove(index)">[x]</a> 
      </div> 
     </div> 
    `, 
    methods: { 
     remove(index) { 
      this.locations.splice(index, 1); 
     } 
    } 
}); 

const app = window.app = new Vue({ 
    el: '#app', 

    data: function() { 
     return { 
      days: [{ 
       name: 'Day 1', 
       locations: [{ 
        name: 'Berlin' 
       }, { 
        name: 'London' 
       }, { 
        name: 'New York' 
       }] 
      }, { 
       name: 'Day 2', 
       locations: [{ 
        name: 'Moscow' 
       }, { 
        name: 'Seul' 
       }, { 
        name: 'Paris' 
       }] 
      }] 
     } 
    }, 

    methods: {} 
}); 

的另一件事 - 你的location-list模板有一個錯誤 - 你是不是關閉<a>元素。您可以使用反引號操作符來創建多行模板,如上例所示,以避免模板錯誤。

此外,您不應該更改通過props傳遞的對象。它在這裏工作,因爲你傳遞的是通過引用傳遞的對象。但是,一個字符串對象得到修改,子組件會導致這個錯誤:

[Vue warn]: Avoid mutating a prop directly...

如果你得到這個錯誤,你可以使用事件機制,作爲這個問題的答案解釋:Delete a Vue child component

+0

這是一個工作jsFiddle以供參考:https://jsfiddle.net/2gab0k3y/ – Mani