programing

v-for를 사용하여 반복할 때 vuej가 크래시됨

prostudy 2022. 6. 25. 20:21
반응형

v-for를 사용하여 반복할 때 vuej가 크래시됨

다음과 같은 대상이 있습니다.

 const iterable = {
    items: [1,2,3,4],
    currentIndex: 0,
    [Symbol.iterator]() {
      const self = this;
      return {
        next() {
          return {
            done: self.currentIndex === self.items.length,
            value: self.items[self.currentIndex++]
          }
        }
      }
    }
  }

루핑할 수 있다for of:

    for(let i of iterable){
        console.log(i)
    }

이제 v-for를 사용하여 반복해야 합니다.

<p v-for="item of iterable" :key="item">{{item}}</p>

그러나 Vuejs는 크래쉬하고 무한 루프 상태가 되는 것처럼 보입니다.브라우저가 크래쉬 하고 다음 메시지가 표시되기 때문입니다.메모리 부족이 발생할 수 있는 크래시 전에 일시 중지됨

요청, 반복 가능한 지원 추가 - 이 기능이 vue 2.6.x에서 병합되어 사용되었다고 합니다. Vuejs 2.6.11을 사용하고 있습니다.

여기 사용 예를 나타냅니다.v-for반복할 수 있습니다.

const iterable = {
  items: [1, 2, 3, 4],

  [Symbol.iterator] () {
    const items = this.items
    const length = items.length
    let currentIndex = -1
    
    return {
      next () {
        currentIndex++
      
        return {
          done: currentIndex >= length,
          value: items[currentIndex]
        }
      }
    }
  }
}

new Vue({
  el: '#app',
  
  data () {
    return { iterable }
  },
  
  methods: {
    onAddClick () {
      this.iterable.items.push(Date.now())
    },
    
    onRemoveClick () {
      this.iterable.items.pop()
    }
  }
})
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>

<div id="app">
  <p v-for="item of iterable">{{ item }}</p>
  <button @click="onAddClick">Add item</button>
  <button @click="onRemoveClick">Remove item</button>
</div>

원래 코드의 주요 문제는 새 반복기를 만들 때 카운터가 리셋되지 않는다는 것입니다.그래서 당신이 처음으로 반복할 수 있는 것을 반복하면 모든 것이 잘 될 것입니다.그러나 두 번째 경우 카운터는 이미 어레이의 끝에 있습니다.수표는self.currentIndex === self.items.length항상 그럴 것이다false~하듯이currentIndex보다 커집니다.length.

동일한 문제를 확인할 수 있습니다.for/of루프. 예:

for(let i of iterable){
  console.log(i)
}

for(let i of iterable){
  console.log(i)
}

첫 번째 루프는 문제없이 동작하지만 두 번째 루프는 절대 종료되지 않습니다.

왜 Vue는 반복 가능한 것을 두 번 반복하려 하는지...

제 추측으로는 당신이 그 사실을 폭로하고 있는 것 같아요iterable경유로data소유물.currentIndex반응하며 렌더링 종속성으로 등록됩니다.그런 다음 이 값이 증가하면 재렌더가 트리거됩니다.이론적으로는 무한 렌더링 재귀가 되지만, 실제로는 끝이 없는 반복 루프 때문에 두 번째 렌더링을 넘지 않습니다.

이 문제를 해결하는 열쇠는currentIndex반복자가 아닌 반복자에게 스코프를 적용했습니다.이를 구현하는 방법은 여러 가지가 있지만 이전 예에서 사용한 방법이 다음과 같습니다.

const iterable = {
  items: [1, 2, 3, 4],

  [Symbol.iterator] () {
    const items = this.items
    const length = items.length
    let currentIndex = -1

    return {
      next () {
        currentIndex++

        return {
          done: currentIndex >= length,
          value: items[currentIndex]
        }
      }
    }
  }
}

여기서currentIndex의 폐막으로 개최되고 있습니다.next방법.또는 반복기 객체의 속성으로 추가할 수도 있습니다.next.

언급URL : https://stackoverflow.com/questions/59797458/vuejs-crashes-when-i-use-v-for-to-iterate-over-a-iterable

반응형