v-for 지시문의 키 값이 vue의 색인이 될 수 없는 이유는 무엇입니까?
vue에서 v-for를 사용할 때 왜 index를 키로 사용할 수 없나요? 다음 글에서는 v-for의 핵심값이 index가 될 수 없는 이유를 소개하겠습니다. 도움이 되셨으면 좋겠습니다!
왜 v-for의 키값은 인덱스가 될 수 없나요?
많은 사람들이 이런 흔한 면접 질문을 하면 바로 가상 DOM
과 diff 알고리즘
에 대해 이야기하기 시작합니다. 虚拟DOM
和 diff算法
了。
讲这些没问题,但如果是我,一定先讲 v-for 的 key 值写成 index 会造成的问题,再讲原理。
曾经我写 v-for, key 值永远都是 index,直到有一天,我这么写造成了线上bug...
来看一下我的线上bug演示吧:
父组件代码 <Child v-for="(item, index) in list" :key="index" :count="item.count" :name="item.name" @delete="handleDelete(index)" /> list: [ { count: 1, name: '第1个元素' }, { count: 2, name: '第2个元素' }, { count: 3, name: '第3个元素' } ] handleDelete(index) { this.list.splice(index, 1) },
如代码和gif演示,点击删除第2个元素,看上去似乎一切正常。
等一下,第三个元素的count值居然变成了2,wtf!!!
惊得我又去看了遍子组件的代码
子组件 <div> <span>{{ name }}</span> count值为:{{ innerCount }} <button @click="$emit('delete')">-</button> </div> props: { count: { type: Number, default: 0 }, name: { type: String, default: '' } }, data() { return { innerCount: this.count } }
感觉也没什么不对的啊。
不信邪,我又多创建了点元素来删除,还试了下排序:
果然,不光删除元素有问题,排序也有问题。
把 key 值改成 item.name 再试一下。
<Child v-for="(item, index) in list" :key="item.name" :count="item.count" :name="item.name" @delete="handleDelete(index)" />
正常了。
这样看来,在 v-for 里把 key 值写成 index,非常危险啊。
在查阅了 vue 官方文档之后,我终于明白了原因:
当 Vue 正在更新使用
v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
不依赖子组件状态
子组件里有一行很关键的代码
data() { return { innerCount: this.count } }
子组件内部定义了 innerCount,这样子组件就有了自己的状态,按照官方文档的说明,这种情况下不能把 index 作为 key 值。
临时 DOM 状态
<div v-for="(item, index) in list1" :key="index"> <input type="text" /> <button @click="delClick(index)">删除</button> </div>
删除了第2项,但是第3项在表单中的3变成了2,跟上面依赖子组件状态的例子是一样的。
总结
写列表渲染时, 依赖子组件状态或临时 DOM 状态的情况,如果有 删除、增加、排序这样的功能,不要把 index 作为 key。
事实上,写列表渲染时,永远不要把 index 做为 key,key 一定要是唯一标识。
至于原因,就要理解 diff
- 온라인 버그
- 가 발생했습니다...
- 제 온라인 버그 데모를 살펴보겠습니다: rrreee
너무 놀라서 다시 서브컴포넌트의 코드를 살펴보니rrreee
아무 문제가 없다는 걸 느꼈습니다. 🎜🎜나는 악을 믿지 않기 때문에 삭제할 요소를 더 만들고 정렬을 시도했습니다: 🎜🎜

🎜Vue가 v-for
를 사용하여 렌더링된 요소 목록을 업데이트할 때 기본적으로 "내부 업데이트"를 사용합니다. 전략. 데이터 항목의 순서가 변경되면 Vue는 데이터 항목의 순서와 일치하도록 DOM 요소를 이동하지 않지만 각 요소를 제자리에 업데이트하고 각 인덱스 위치에서 올바르게 렌더링되도록 합니다. 🎜
🎜이 기본 모드는 효율적이지만 🎜하위 구성 요소 상태나 임시 DOM 상태(예: 양식 입력 값)에 의존하지 않는 목록 렌더링 출력🎜에만 적합합니다. 🎜🎜🎜하위 구성 요소의 상태에 의존하지 않습니다🎜🎜🎜하위 구성 요소에 매우 중요한 코드 줄이 있습니다🎜rrreee🎜innerCount는 하위 구성 요소에서 내부적으로 정의되므로 하위 구성 요소는 자체 상태를 갖습니다. 공식 문서에 따르면 이 경우 index를 키 값으로 사용할 수 없습니다. 🎜🎜🎜임시 DOM 상태🎜🎜rrreee🎜

요약🎜🎜목록 렌더링 시 하위 구성 요소의 상태나 임시 DOM 상태에 따라 다릅니다. 삭제, 추가, 정렬 등의 기능이 있는 경우에는 사용하지 마세요. 인덱스를 키로 사용합니다. 🎜🎜실제로 렌더링용 목록을 작성할 때 인덱스를 키로 사용하지 마십시오. 키는 고유 식별자여야 합니다. 🎜🎜이유를 이해하려면 diff
알고리즘을 이해해야 합니다. 🎜🎜답변할 질문: 🎜🎜🎜왜 키를 임의의 숫자나 타임스탬프로 쓸 수 없나요? 🎜🎜Key 왜 고유 식별자여야 합니까? 🎜🎜🎜걱정하지 마세요. Vue 이슈와 관련된 글 100개를 작성하도록 플래그를 설정해 두었으니 다음 글에서 천천히 분석해 보겠습니다. 🎜🎜제 Vue 시리즈 기사가 프런트엔드 분야에서 여러분에게 도움이 되기를 바랍니다~🎜🎜[관련 추천: 🎜vue.js 비디오 튜토리얼🎜]🎜
위 내용은 v-for 지시문의 키 값이 vue의 색인이 될 수 없는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

vue.js에서 bootstrap 사용은 5 단계로 나뉩니다 : Bootstrap 설치. main.js.의 부트 스트랩 가져 오기 부트 스트랩 구성 요소를 템플릿에서 직접 사용하십시오. 선택 사항 : 사용자 정의 스타일. 선택 사항 : 플러그인을 사용하십시오.

HTML 템플릿의 버튼을 메소드에 바인딩하여 VUE 버튼에 함수를 추가 할 수 있습니다. 메소드를 정의하고 VUE 인스턴스에서 기능 로직을 작성하십시오.

vue.js의 시계 옵션을 사용하면 개발자가 특정 데이터의 변경 사항을들을 수 있습니다. 데이터가 변경되면 콜백 기능을 트리거하여 업데이트보기 또는 기타 작업을 수행합니다. 구성 옵션에는 즉시 콜백을 실행할지 여부와 DEEP를 지정하는 즉시 포함되며, 이는 객체 또는 어레이에 대한 변경 사항을 재귀 적으로 듣는 지 여부를 지정합니다.

VUE 멀티 페이지 개발은 vue.js 프레임 워크를 사용하여 응용 프로그램을 구축하는 방법입니다. 여기서 응용 프로그램은 별도의 페이지로 나뉩니다. 코드 유지 보수 : 응용 프로그램을 여러 페이지로 분할하면 코드를보다 쉽게 관리하고 유지 관리 할 수 있습니다. 모듈 식 : 각 페이지는 쉬운 재사용 및 교체를 위해 별도의 모듈로 사용할 수 있습니다. 간단한 라우팅 : 페이지 간의 탐색은 간단한 라우팅 구성을 통해 관리 할 수 있습니다. SEO 최적화 : 각 페이지에는 자체 URL이있어 SEO가 도움이됩니다.

vue.js는 이전 페이지로 돌아갈 수있는 네 가지 방법이 있습니다. $ router.go (-1) $ router.back () 사용 & lt; router-link to = & quot;/quot; Component Window.history.back () 및 메소드 선택은 장면에 따라 다릅니다.

NetflixusesAcustomFrameworkCalled "Gibbon"BuiltonReact, NotreactorVuedirectly.1) TeamExperience : 2) ProjectComplexity : vueforsimplerProjects, 3) CustomizationNeeds : reactoffersmoreflex.4)

vue.js가 트래버스 어레이 및 객체에 대한 세 가지 일반적인 방법이 있습니다. V- 결합 지시문은 V-FOR와 함께 사용하여 각 요소의 속성 값을 동적으로 설정할 수 있습니다. .MAP 메소드는 배열 요소를 새 배열로 변환 할 수 있습니다.

vue.js에서 JS 파일을 참조하는 세 가지 방법이 있습니다. & lt; script & gt; 꼬리표;; mounted () 라이프 사이클 후크를 사용한 동적 가져 오기; Vuex State Management Library를 통해 수입.
