source

원치 않는 동작에 대한 VueJs v-

lovecheck 2022. 10. 30. 17:59
반응형

원치 않는 동작에 대한 VueJs v-

v-for 목록을 렌더링하는 데 사용되는 어레이를 수정할 때마다 이 문제가 발생합니다.

세 가지 항목의 v-for 목록이 있다고 가정해 보겠습니다.

<ul>
  <li v-for="item in items"></li>
<ul></ul>

<ul>
  <li>One</li> <!-- Has focus or a specific child component -->
  <li>Two</li>
  <li>Three</li>
</ul>

항목 배열에 새 항목 추가:

<ul>
  <li>New Item</li> <!-- Focuses on this item, the child component seems to be moved here -->
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

초점은 움직이는 것 같은데...

문제를 나타내는 바이올린을 봐주세요.https://jsfiddle.net/gu9wyctr/

이 행동에는 정당한 이유가 있다는 것은 알지만, 그것을 관리하거나 완전히 피해야 합니다.아이디어?

편집:

제 설명이 좀 애매하다는 걸 이제야 깨달았어요.이 문제를 설명하기 위한 업데이트된 바이올린을 소개합니다.https://jsfiddle.net/keligijus/d1s4mjj7/

문제는 입력 텍스트가 다른 요소로 이동된다는 것입니다.

나의 실제 삶의 예.포럼 같은 게시물 목록이 있어요.각 투고에는 회신을 위한 입력이 있습니다.다른 사용자가 응답을 입력하는 동안 다른 사용자가 새 게시물을 게시하면 해당 사용자가 입력한 입력 내용이 다른 게시물로 이동됩니다.바이올린의 예처럼요

키를 제공하는 이 정답입니다!

https://vuejs.org/v2/guide/list.html#key

Vue는 v-for로 렌더링된 요소 목록을 업데이트할 때 기본적으로 "임플레이스 패치" 전략을 사용합니다.데이터 항목의 순서가 변경된 경우 DOM 요소를 항목 순서와 일치하도록 이동하는 대신 Vue는 각 요소에 패치를 적용하여 특정 인덱스에서 렌더링해야 하는 내용을 반영하도록 합니다.이는 Vue 1.x의 track-by="$index" 동작과 유사합니다.

이 기본 모드는 효율적이지만 목록 렌더 출력이 하위 구성요소 상태 또는 임시 DOM 상태(예: 양식 입력 값)에 의존하지 않는 경우에만 적합합니다.

Vue가 각 노드의 ID를 추적하여 기존 요소를 재사용하고 재정렬할 수 있도록 힌트를 제공하려면 각 항목에 고유한 키 특성을 제공해야 합니다.키의 이상적인 값은 각 항목의 고유 ID입니다.이 특수 특성은 1.x의 추적 기준과 대략 동일하지만 특성처럼 작동하므로 v-bind를 사용하여 동적 값에 바인딩해야 합니다(여기 줄임말 사용).

<li v-for="(item, index) in items" :key="'item-'+item">
  <input :id="'item-'+index" type="text" style="width:80%;">
</li>

기능이 동작하는 것을 나타내기 위해 fiodle이 업데이트되었습니다.

이것을 시험해 보세요.

var app = new Vue({
  el: '#app',
  data: {
    messages: [
      { message: 'Hello Vue!', id: 0 },
      { message: 'Hello Vuex!', id: 1 },
      { message: 'Hello VueRouter!', id: 2 }
    ],
    msg: null,
    focus: 'item-1'
  },
  mounted () {
  	document.getElementById(this.focus).focus()
  	setTimeout(() => {
    	this.messages.unshift({ message: 'Focus moves!', id: 3 })
    }, 2000)
  	setTimeout(() => {
    	this.messages.unshift({ message: 'Moves again...', id: 4 })
      this.msg = `I suppose this happens because of the way DOM is updated and I understand there must a good reason for this. However I need to avoid this behaviour. How can I do this?`
    }, 4000)
  },
  updated: function () {
  	document.getElementById(this.focus).focus()
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(message, index) in messages">
      <input :id="'item-'+message.id" type="text" v-model="message.message" style="width:80%;">
    </li>
    <li v-if="msg">{{msg}}</li>
  </ul>
</div>

기본적으로 새로운 아이템이 추가되어도 id를 동일하게 만들고, 그 후 초점을 맞춘 아이템을 추적하여 업데이트 후에도 다시 포커스를 맞출 수 있습니다.

언급URL : https://stackoverflow.com/questions/45528639/vuejs-v-for-unwanted-behaviour

반응형