Когда я манипулирую dom, v-for больше не синхронизируется c с реактивным массивом - PullRequest
0 голосов
/ 29 мая 2020

Это очень сбивает с толку - и я бы даже подумал, что здесь ошибка.

https://jsbin.com/qadunor/edit?html, js, вывод

updateList(containerDom) {
  return () => {
    Array.from(containerDom.querySelectorAll(".list-group-item")).forEach((domItem, idx) => {
      let listItemIndex = this.list.findIndex(listItem => listItem.name === domItem.innerText)
      let listItem = this.list[listItemIndex]
      listItem.pos = idx
      this.list.splice(listItemIndex, 1, listItem)
    })
  }
}

Если перетащить от первого элемента списка («животное») до последнего элемента списка («нарукавная повязка»), чтобы по существу выполнить обмен (с помощью Sortable. js), вы увидите, что список является реактивным - вы можете увидеть это в вывод - он обновил свою позицию, но "v-for" l oop не отреагировал должным образом.

Он каким-то образом реагирует - но не правильно, как вы увидите (неправильно сбрасывает повязку во вторую позицию). Теперь, если бы я просто использовал Sortable. js, своп работал нормально (ie если я не обрабатываю событие onUpdate - просто закомментируйте его). Я знаю, что могу использовать VUE .draggable (или как там он называется, где он поддерживает внутренний список, но по ряду более сложных причин я не могу использовать эту библиотеку). Мой вариант использования, в котором я хочу использовать вышеупомянутую технику, здесь не имеет значения - я просто хочу знать, почему именно этот способ не работает для "v-for".

Я знаю, что это как-то связано с фактом that Sortable. js выполняет свои собственные манипуляции с DOM, но я ожидал, что после того, как массив списка будет изменен, v-for l oop должен отреагировать соответствующим образом - но это как бы сбивает с толку то, что в настоящее время находится в DOM .

Ответы [ 2 ]

1 голос
/ 01 июня 2020

Я думаю, причина того, что это не работает, довольно просто потому, что я управляю dom напрямую (через Sortable. js), но когда дело доходит до обновления виртуального dom, которым управляет vue, он не знает о произошедшие манипуляции с dom и не обновляют должным образом виртуальный dom (и, следовательно, реальный dom) при изменении реактивного списка.

Это можно рассматривать как ошибку на стороне vue - Я ожидаю, что "v-for" l oop будет отражать реактивный список. Но это также можно рассматривать как ограничение. Это компромисс - vuejs не может проверять реальный и виртуальный домены по соображениям производительности?

Так что, чтобы справиться с этим, мне, вероятно, понадобится

  • , чтобы позвольте перетаскиванию происходить и позволить управлять домом напрямую (через Sortable. js),
  • , затем проверьте новый порядок в dom и сделайте заметки о новом порядке,
  • затем отмените манипуляции с домом,
  • , а затем используйте сделанные мной заметки и обновите реактивный список,
  • , который, в свою очередь, обновит виртуальный дом.

Таким образом, шаг, который отсутствует в моем примере кода, - это код, который отменяет манипуляции с dom.

0 голосов
/ 01 июня 2020

Я имел в виду, что вы можете создать точную копию вашего текущего списка, а затем поменять местами все имена (я не уверен, почему вы слишком усложняете это, используя forEach, поскольку updateList функция передает oldIndex и newIndex)

  data() {
     let list = [
        { name: "animal", pos: 0 },
        { name: "aloe", pos: 1 },
        { name: "arm", pos: 2 },
        { name: "arsenal", pos: 3 },
        { name: "antenna", pos: 4 },
        { name: "antler", pos: 5 },
        { name: "armband", pos: 6 },
      ]
    return {
      original_list: JSON.parse(JSON.stringify(list)),
      list: list,
    };    
  },

  methods: {
    listToJSON(list) {
      return JSON.stringify(list, null, 2)
    },
    updateList(context) {
      let old = context.oldIndex
      let $new = context.newIndex
      let temp_name = this.original_list[old].name
      this.original_list[old].name = this.original_list[$new].name
      this.original_list[$new].name = temp_name
    }
  },

https://jsbin.com/pulapopave/1/edit?html, js, вывод

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...