>웹 프론트엔드 >View.js >Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

青灯夜游
青灯夜游앞으로
2022-09-23 20:03:101624검색

vue왜 인덱스를 고유 식별자로 사용할 수 없나요? 다음 글에서는 Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유를 소개하겠습니다. 도움이 되길 바랍니다!

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

여기에는 네이티브 js의 DOM 작업과 가상 DOM이 가져온 최적화가 포함됩니다. 다음은 두 부분으로 나누어

  • 가상 DOM
  • 인덱스를 키로 사용할 수 없는 이유에 대해 설명합니다. : vuejs video Tutorial

1. Virtual DOM

먼저 DOM 노드를 기본적으로 작동하는 방법을 살펴보겠습니다. 하지만 DOM 작업에 대한 브라우저의 반응은 매우 에너지를 소모합니다. 작업(브라우저에서 페이지를 렌더링하는 과정을 참조하세요)

nbsp;html>



    <meta>
    <meta>
    <meta>
    <title>Document</title>



    <div>
        <ul></ul>
    </div>
    <script>
        let ul = document.querySelector(&#39;ul&#39;)
        for (let i = 0; i < 3; i++) {
            let li = document.createElement(&#39;li&#39;)
            li.innerHTML = i + 1
            ul.appendChild(li)
        }
    </script>


Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

또한 동적으로 변경되는 많은 js 코드로 인해 브라우저가 재정렬되고 에너지 소비가 상상해 보세요. 일부 노드가 변경되면 변경된 노드를 로컬로 재배치하면 성능이 많이 절약되지 않을까요? ? ? Vue에서 소개하는 가상 DOM은 이 방법을 사용합니다. 다음은 vue 코드의 일부입니다

nbsp;html>



    <meta>
    <meta>
    <meta>
    <script></script>
    <title>Document</title>



    <div>
        <ul>
            <item></item>
        </ul>
        <button>change</button>
    </div>

    <script>
        new Vue({
            el: &#39;#app&#39;,
            data() {
                return {
                    list: [1, 2, 3]
                }
            },
            methods: {
                change() {
                    this.list.reverse()
                }
            },
            components: {
                item: {
                    props: [&#39;num&#39;],
                    template: `
            <div>
              {{num}}  
            
          `,
                    name: &#39;child&#39;
                }
            }
        })
    </script>


Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

변경 버튼을 클릭하면

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

네이티브 js가 이러한 작업을 수행하면 필연적으로 발생합니다. 재배치했는데 페이지가 부분적으로 변경된 것 뿐인데 Vue는 virtual DOM을 도입한 후 에너지 소비를 크게 절감했습니다

그럼 virtual DOM이란 무엇일까요?

vue에서는 렌더링 기능을 실행하기 전에 가상 노드 트리를 얻을 수 있으며, 가상 노드 트리를 사용하여 페이지를 렌더링할 수 있습니다. 페이지 DOM 노드가 동적으로 변경되면 렌더링하기 전에 새로 생성된 가상 노드가 마지막으로 생성된 가상 노드와 비교되고 다른 부분만 렌더링됩니다. 각 가상 노드는 컨테이너 레이어의 특성을 설명하는 객체입니다. 다음은 vue 코드에서 변경 버튼을 누르기 전의 가상 노드 트리입니다

vndoe = {
    tag: 'ul',
    children: [
        { tag: 'li',key:0, children: [{ vnode: { text: '3' } }] },
        { tag: 'li',key:1, children: [{ vnode: { text: '2' } }] },
        { tag: 'li',key:2, children: [{ vnode: { text: '1' } }] }

    ]
}复制代码

변경을 클릭하면 새로운 가상 노드 트리가 생성되어 그것과 비교됩니다

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

비교 후, 서로 다른 장소가 렌더링됩니다

그렇다면 두 가상 노드 수의 차이를 어떻게 찾을 수 있을까요? 여기에는 vue 소스 코드의 diff 알고리즘이 포함됩니다

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

라이프 사이클이 마운트된 후 데이터 소스가 변경되는 한 감시자 관찰자의 콜백이 트리거되어 뷰 업데이트를 구동합니다. vm._update(v_rander())
_update는 차이점을 찾기 위해 _patch_에 vnode를 생성합니다
_patch_에서 시작되는 것은 diff 알고리즘입니다

key는 두 가지를 찾는 데 있어 diff 알고리즘을 더 정확하게 만들기 위한 고유 식별자입니다. 비교해야 하는 노드

2. 그러면 왜 인덱스를 키로 사용할 수 없나요

이전 코드를 살펴보겠습니다. diff 알고리즘에서 키는 두 개의 가상 노드 트리가 있을 때 고유 식별자입니다. 비교하면 동일한 키 값이 발견됩니다. 비교를 통해 키 값은 동일하지만 내부 데이터가 다른 것으로 확인됩니다. diff 알고리즘은 실제로는 변경되었음을 확인하고 다시 렌더링합니다. 위치를 변경했습니다. 고유 식별자 ID를 추가하면

nbsp;html>    <meta>    <meta>    <meta>    <script></script>    <title>Document</title>    <div>        <ul>            <item></item>        </ul>        <button>change</button>    </div>    <script>        new Vue({            el: &#39;#app&#39;,            data() {                return {                    list: [{                        n: 1,                        id: 0
                    }, {                        n: 2,                        id: 1
                    }, {                        n: 3,                        id: 2
                    }, ]
                }
            },            methods: {                change() {                    this.list.reverse()
                }
            },            components: {                item: {                    props: [&#39;num&#39;],                    template: `
            <div>
              {{num}}  
            
          `,                    name: &#39;child&#39;
                }
            }
        })  </script>复制代码

클릭 변경 후 가상 노드 트리 비교

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

diff 알고리즘이 비교를 위해 동일한 키 값을 찾은 후 해당 키가 값은 동일하지만 내부 데이터도 동일합니다. 다시 렌더링되지는 않지만 위치가 크게 변경됩니다. 브라우저 소비를 크게 절약하므로 인덱스를 키로 사용하면 diff의 최적화가 실패하게 됩니다(재사용성이 감소하고 가상 돔의 원래 의도)

데이터 인덱스를 키로 삭제하면 단점이 더욱 명백해집니다

nbsp;html>    <meta>    <meta>    <meta>    <script></script>    <title>Document</title>    <div>        <ul>            <li>                <item></item>            </li>        </ul>        <button>del</button>    </div>    <script>        new Vue({            el: &#39;#app&#39;,            data() {                return {                    list: [1, 2, 3]
                }
            },            methods: {                del() {                    this.list.splice(0, 1)
                }
            },            components: {                item: {                    template: &#39;<div>{{Math.random()}}&#39;
                }
            }
        })    </script>复制代码

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

삭제 버튼을 누른 후

Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석

실제로 마지막 항목을 삭제한 것으로 확인되었는데, 데이터를 삭제한 후 배열의 특성상 남은 데이터의 첨자 인덱스와 키가 -1로 변경되기 때문입니다. 즉, 두 번째, 3개의 데이터 키가 1, 2에서 0,1로 변경되면 diff 알고리즘은 키 0,1의 데이터 내용이 변경되고 키 3의 내용이 삭제되었다고 간주하므로 첫 번째와 두 번째 데이터를 다시 렌더링하고 삭제합니다. 세 번째 데이터인데 실제로는 세 번째 데이터를 삭제했습니다. 하나의 콘텐츠, 두 번째, 세 번째는 키 값 변경입니다. Vue는 하위 구성 요소의 텍스트 내용을 깊이 비교하지 않습니다. 키를 사용하여 비교하면 가상 DOM 트리가 잘못 작동하고 잘못 렌더링됩니다.

( 학습 영상 공유:

웹 프론트엔드 개발, 프로그래밍 기초 영상)

위 내용은 Vue가 인덱스를 고유 식별자로 사용할 수 없는 이유에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제