Javascript Vue删除组件动态列表中错误的HTML节点

Javascript Vue删除组件动态列表中错误的HTML节点,javascript,vue.js,vuejs2,vue-component,Javascript,Vue.js,Vuejs2,Vue Component,我正在试验Vue.JS,并用它动态组合组件 有一个奇怪的问题,尽管它似乎正确地更新了数据,但如果我通过调用splice()删除其中一个框,它总是会删除呈现的HTML中的最后一项 这里有一个小提琴的例子。我正在测试Chrome 仅供子孙后代参考,以下是Vue组件代码: Vue.component('content-longtext', { template: '#content-longtext', props: { model: { type: String, required

我正在试验Vue.JS,并用它动态组合组件

有一个奇怪的问题,尽管它似乎正确地更新了数据,但如果我通过调用
splice()
删除其中一个框,它总是会删除呈现的HTML中的最后一项

这里有一个小提琴的例子。我正在测试Chrome

仅供子孙后代参考,以下是Vue组件代码:

Vue.component('content-longtext', {
  template: '#content-longtext',
  props: {
    model: { type: String, required: true },
    update: { type: Function, required: true }
  },
  data() {
    return {
      inputData: this.model
    }
  },
  methods: {
    updateContent(event) {
      this.update(event.target.value)
    }
  },
})

Vue.component('content-image', {
  template: '#content-image',
})

Vue.component('content-list', {
  template: '#content-list-template',
  props: {
    remove: { type: Function, required: true },
    update: { type: Function, required: true },
    views: { type: Array, required: true }
  },
  methods: {
    removeContent(index) {
      this.remove(index)
    },
    updateContent(index) {
      return (content) => this.update(index, content)
    },
  },
})

Vue.component('content-editor', {
  template: '#content-editor',
  data() {
    return {
      views: [
        {type: 'content-longtext', model: 'test1'},
        {type: 'content-longtext', model: 'test2'},
        {type: 'content-longtext', model: 'test3'},
        {type: 'content-longtext', model: 'test4'},
        {type: 'content-longtext', model: 'test5'},
      ],
    }
  },
  methods: {
    newContentBlock(type) {
      this.views.push({type: 'content-longtext', model: ''})
    },
    updateContentBlock(index, model) {
      this.views[index].model = model
    },
    removeContentBlock(index) {
      this.views.splice(index, 1)
    },
  },
})

let app = new Vue({
  el: '#app'
})

多亏了文档,我成功地解决了这个问题

问题的关键是,如果您还没有唯一的键,则需要将对象的数组索引存储在对象本身中,这是因为当您改变源数组时,您也改变了它的键,并且对于渲染时的Vue而言,最后一项丢失,而不是删除的项

views: [
  {index: 0, type: 'content-longtext', model: 'test1'},
  {index: 1, type: 'content-longtext', model: 'test2'},
  {index: 2, type: 'content-longtext', model: 'test3'},
  {index: 3, type: 'content-longtext', model: 'test4'},
  {index: 4, type: 'content-longtext', model: 'test5'},
],

...

newContentBlock(type) {
  this.views.push({index: this.views.length, type: 'content-longtext', model: ''})
},
存储数组索引后,需要将
:键
绑定添加到模板中的迭代器,并绑定存储的值

<div v-for="(currentView, index) in views" :key="currentView.index">
  <component :is="currentView.type" :model="currentView.model" :update="updateContent(index)"></component>
  <a v-on:click="removeContent(index)">Remove</a>
</div>

多亏了文档,我成功地解决了这个问题

问题的关键是,如果您还没有唯一的键,则需要将对象的数组索引存储在对象本身中,这是因为当您改变源数组时,您也改变了它的键,并且对于渲染时的Vue而言,最后一项丢失,而不是删除的项

views: [
  {index: 0, type: 'content-longtext', model: 'test1'},
  {index: 1, type: 'content-longtext', model: 'test2'},
  {index: 2, type: 'content-longtext', model: 'test3'},
  {index: 3, type: 'content-longtext', model: 'test4'},
  {index: 4, type: 'content-longtext', model: 'test5'},
],

...

newContentBlock(type) {
  this.views.push({index: this.views.length, type: 'content-longtext', model: ''})
},
存储数组索引后,需要将
:键
绑定添加到模板中的迭代器,并绑定存储的值

<div v-for="(currentView, index) in views" :key="currentView.index">
  <component :is="currentView.type" :model="currentView.model" :update="updateContent(index)"></component>
  <a v-on:click="removeContent(index)">Remove</a>
</div>

是的!我正要发布类似的东西。感谢您“您需要将对象的数组索引存储在对象本身中”,这是真正的解决方案!我看到的大多数解决方案都建议使用对象而不是数组。对我来说,这看起来干净多了。是的!我正要发布类似的东西。感谢您“您需要将对象的数组索引存储在对象本身中”,这是真正的解决方案!我看到的大多数解决方案都建议使用对象而不是数组。这对我来说似乎干净多了。