BeeLee
BeeLee

Reputation: 183

v-for loop items not immediately updating in Vue

I will explain point by point as it can be a quiet complex.

Basically, I'm storing each selected text to selectionArray. Each selectedText is a string inside an object. So SelectionArray becomes an array of objects like this On the first selection:

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

On the second selection the array is updated:

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

And so on... At the end, I loop with v-on on items array which is equal to selectionArray with:

this.items = selectionArray

For the moment I'm almost there but something missing as I don't see the modification in live I have to make a useless modification on the HTML (weird) for example to be able to see the result. I'm suspecting the created method but I need help please at least a logic way of investigation. Thx

Here is the code:

<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>

Upvotes: 0

Views: 4825

Answers (1)

JakeParis
JakeParis

Reputation: 11210

Vue can't detect addition/deletion of array items and object properties. Read the Caveats section of the Vue guide, there it gives you some ideas on how to workaround that problem.

Here's what it says:

Due to limitations in JavaScript, Vue cannot detect the following changes to an array:

  1. When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
  2. When you modify the length of the array, e.g. vm.items.length = newLength

To overcome caveat 1, both of the following will accomplish the same as vm.items[indexOfItem] = newValue, but will also trigger state updates in the reactivity system:

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

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

To deal with caveat 2, you can use splice:

example1.items.splice(newLength)

Upvotes: 7

Related Questions