缺陷效果图

v-for的缺陷.gifv-for的缺陷2.gif
从上图可以看出:你会发现第一li与第二个li互换啦位置,但是你会发现输入框的内容没有跟着zzz走。反而给啦xxx

知识点

Vue更新使用v-for渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素:
就地更新说白就是;Vue更新的是数据,他不会移动dom,移动dome是很浪费性能的,而且它的就地更新,更新的是数据,数据与文本是绑定的,并没有跟元素绑定,它就把数据替换掉,其余的就没有更新

源码

  1. <ul id="app">
  2. <li v-for="(person, index) in persons">
  3. {{ person }}
  4. <input type="text" />
  5. <button @click="handleClick(index)">下移</button>
  6. </li>
  7. </ul>
  1. const vm = new Vue({
  2. el: '#app',
  3. data: {
  4. persons: ['zzz', 'xxx', 'ccc', 'vvvv']
  5. },
  6. methods: {
  7. handleClick (index) {
  8. const deleteItem = this.persons.splice(index, 1);
  9. console.log(index)
  10. this.persons.splice(index + 1, 0, ...deleteItem);
  11. }
  12. }
  13. })

详讲

没有触发事件前
image.png
触发第一按钮的单击事件
image.png
控制台打印的index
image.png
当我们再次触发第一个按钮的单击事件
image.png
在看控制台的索引
image.png
说明Vue 只跟新啦数据,其余完全没有更新

在”就地复用”策略中,点击按钮,输入框不随文本一起下移,是因为输入框没有与数据绑定,所以vuejs默认使用已经渲染的dom,然而文本是与数据绑定的,所以文本被重新渲染。这种处理方式在vue中是默认的列表渲染策略,因为高效。
这个默认的模式是高效的,但是在更多的时候,我们并不需要这样去处理,所以,为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,我们需要为每项提供一个唯一key特性,Vue会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素