Элементы цикла v-for не обновляются сразу в Vue

Я объясню, как это может быть тихий комплекс.

  • Я выделяю текст с помощью мыши или трекпада, а при наведении мыши выделенный текст сохраняется в массиве объектов. Каждый объект содержит выделенный текст.

  • Я хочу зациклить этот массив, чтобы иметь возможность отображать все выделения по одному, пока я выбираю другой текст.

По сути, я сохраняю каждый выделенный текст в selectionArray. Каждый selectedText является строкой внутри объекта. Таким образом, SelectionArray становится массивом объектов, подобных этому при первом выделении:

[
 {selectedText: '...string...'}
]

При втором выборе массив обновляется:

[
 {selectedText: '...string...'},
 {selectedText: '...another string...'}
]

И так далее... В конце я зацикливаюсь с v-on на массиве items, который равен selectionArray with:

this.items = selectionArray

На данный момент я почти на месте, но чего-то не хватает, так как я не вижу изменений вживую, я должен сделать бесполезную модификацию HTML (странно), например, чтобы увидеть результат. Я подозреваю, что создан метод, но мне нужна помощь, по крайней мере, логичный способ расследования. Спасибо

Вот код:

<template>
  <main class='wrapper'>
    <section class='wrapper-copy'>
      <div class='copy'>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis sequi dolorum soluta pariatur asperiores. Recusandae atque nesciunt ipsa velit impedit fugit enim, quia explicabo adipisci sunt earum laudantium illo. Tenetur.
Animi magnam corrupti atque mollitia eaque enim, voluptatum magni laboriosam vel possimus reprehenderit aut doloribus inventore repellat aliquam voluptatem esse ut saepe at iusto qui quibusdam doloremque exercitationem ipsam. Dicta.
In animi nobis accusamus nemo repellat dicta a repellendus provident accusantium fugit voluptas minus laudantium reiciendis cumque, amet porro maiores quisquam? Ullam aut voluptatem delectus cum rerum perferendis vero laudantium!
      </div>

    </section>
    <article class="wrapper-select">
      <div class="select">
        <div id='input'
             class='selected-copy'
             v-for='(item, index) in items' 
             :key='item.index'>
          <div class='index'>{{ index }} </div>
          <p class='selection'> {{ item.selectedText }} </p>
        </div>
      </div>
    </article>
  </main>
</template>

<script>
  export default {
    name: 'app',
    data () {
      return {
        items: []
      }
    },
    created () {
      var selectionArray = []
      function storeSelection () {
        var selectedText = window.getSelection().toString()
        if (selectedText.length && selectionArray.indexOf(selectedText) === -1) {
          selectionArray[selectionArray.length] = {selectedText}
        }
        console.log(selectionArray)
      }
      document.addEventListener('mouseup', storeSelection)
      this.items = selectionArray
      console.log(this.items)
    }
  }
</script>

1 ответ

Решение

Vue не может обнаружить добавление / удаление элементов массива и свойств объекта. Прочитайте раздел " Предостережения " в руководстве по Vue, где вы найдете некоторые идеи о том, как обойти эту проблему.

Вот что это говорит:

Из-за ограничений в JavaScript Vue не может обнаружить следующие изменения в массиве:

  1. Когда вы непосредственно устанавливаете элемент с индексом, например, vm.items[indexOfItem] = newValue
  2. Когда вы изменяете длину массива, например, vm.items.length = newLength

Чтобы преодолеть предостережение 1, оба следующих действия будут выполняться так же, как vm.items[indexOfItem] = newValue, но также будут запускать обновления состояния в системе реактивности:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)

// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)

Чтобы справиться с caveat 2, вы можете использовать соединение:

example1.items.splice(newLength)
Другие вопросы по тегам