При удалении компонента vue из списка всегда удаляется последний элемент в списке - PullRequest
0 голосов
/ 03 мая 2018

Я прочитал документацию для рендеринга пользовательских компонентов в списке, используя v-for здесь .

Но по какой-то причине я не могу заставить это работать. Он всегда удаляет последний компонент вместо того, который я отправляю в индексе. Есть идеи, почему он не работает?

Моя версия VUE JS: 2.5.16.

Использование PHPStorm IDE и запуск в Docker (контейнер Linux)

И Laravel mix (у меня есть "laravel-mix": "0. *" запись в package.json) для использования webpack и компиляции модулей JS.

Вот часть моего кода

// Parent Component JS
<template>
    <ul>
        <li
            is="child-component"
            v-for="(child, index) in componentList"
            :key="index"
            :myVal="Something...."
            @remove="dropField(index)"
            @add-custom-field="addField"
        ></li>
    </ul>
</template>

<script>
    import childComponent from './ChildComponent';

    export default {
        name: 'CustomList',

        components: {'child-component' :childComponent},

          data() {
            return {
                componentList: []
            }
          },

       methods: {
            addField() {
                console.log('Handling add-custom-field  field...');
                this.componentList.push(childComponent);
            },

            dropField(index) {
                console.log(`I am deleting the component with index = ${index}  from listview in parent...`);
                this.componentList.splice(index, 1); 
            }
        }
    }


// Child Component JS

<template>
    <div>
       <input type="text" v-model="currentValue" /><button @click.prevent="$emit('remove')" > Remove </button>
    </div
</template>
<script>
  export default {
     props: { myVal : '' },
     data() { return { currentValue: ''} },
     created() {this.currentValue = this.myVal;}

  }
</script>

1 Ответ

0 голосов
/ 03 мая 2018

Проблема вызвана стратегией in-place patch »для v-for . Это означает, что Vue не будет перестраивать все дочерние элементы при удалении одного элемента из componentList.

Проверьте Руководство Vue по стратегии «исправления на месте» для v-for :

Когда Vue обновляет список элементов, отображаемых с помощью v-for, по умолчанию используется стратегия «патч на месте». Если порядок данных элементы изменились, вместо перемещения элементов DOM в соответствии с В порядке расположения элементов Vue исправит каждый элемент на месте и убедится он отражает то, что следует отображать по этому конкретному индексу.

На самом деле вы уже удалили последний элемент, но проблема в том, что свойство data = currentValue первого и второго дочерних элементов было 'a', 'b' при первом подключении. Позже, когда Vue выполнит повторную визуализацию (удалит последний дочерний элемент), свойство data = currentValue сохранит то же значение, хотя prop = myVal уже изменилось.

Посмотрите на демонстрацию ниже, я добавил один вход и связал myVal, вы увидите различия.

Vue.config.productionTip = false

let childComponent = Vue.component('child', {
  template: `<div class="item">
      <p>Index:{{parentIndex}} => <button @click.prevent="removed()" > Remove </button>
      Data:<input type="text" v-model="currentValue" />Props:<input type="text" v-bind:value="myVal" />
      </p>       
    </div>`,
     props: { 'myVal':{
          type: String,
          default: ''
        } ,
        'parentIndex': {
          type: Number,
          default: 0
        }
      },
     data() {
       return { 
        currentValue: ''
       } 
     },
     mounted() {
      this.currentValue = this.myVal
     },
     methods: {
      removed: function () {
        this.$emit('remove')
      }
     }
})


app = new Vue({
  el: "#app",
  data() {
    return {
        componentList: ['a', 'b', 'c'],
        componentType:childComponent
    }
  },

  methods: {
    addField() {
        console.log('Handling add-custom-field  field...');
        this.componentList.push(childComponent);
    },

    dropField(index) {
        console.log(`I am deleting the component with index = ${index}  from listview in parent...`);
        this.componentList.splice(index, 1); 
    }
  }
})
li:nth-child(odd) {
  background-color:#d0d5dd;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
    <ul>
        <li v-for="(child, index) in componentList"><div
            :is="componentType"
            :key="index"
            :my-val="child"
            :parent-index="index"
            @remove="dropField(index)"
            @add-custom-field="addField"
        >{{child}}</div></li>
    </ul>
</div>
...