最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - v-for loop items not immediately updating in Vue - Stack Overflow

programmeradmin4浏览0评论

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

  • I highlight a text with my mouse or trackpad and on mouseup the highlighted text is stored on an array of objects. Each object contains the selected text.

  • I wish to loop on that array to be able to display all selection one by one as long as I'm selecting different text.

Basically, I'm storing each selected text to selectionArray. Each selectedText is a string inside an object. So SelectionArray bees 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>

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

  • I highlight a text with my mouse or trackpad and on mouseup the highlighted text is stored on an array of objects. Each object contains the selected text.

  • I wish to loop on that array to be able to display all selection one by one as long as I'm selecting different text.

Basically, I'm storing each selected text to selectionArray. Each selectedText is a string inside an object. So SelectionArray bees 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>
Share Improve this question edited May 13, 2021 at 20:10 JakeParis 11.2k6 gold badges43 silver badges67 bronze badges asked Jan 11, 2018 at 0:32 BeeLeeBeeLee 1935 silver badges15 bronze badges 3
  • Hard to understand, what you've meant. If you are trying to show selections one by one, why don't you add setTimeout or setInterval? Do you remember nexttick feature of vuejs? – shukshin.ivan Commented Jan 11, 2018 at 2:00
  • @shukshin.ivan Sorry for the bad explanation and thank you for your time. I will edit my issue now and please tell me if it's better – BeeLee Commented Jan 11, 2018 at 2:10
  • @shukshin.ivan done! – BeeLee Commented Jan 11, 2018 at 2:17
Add a ment  | 

1 Answer 1

Reset to default 7

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 overe caveat 1, both of the following will acplish 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)
发布评论

评论列表(0)

  1. 暂无评论