可以简单的这样理解:没有 key 属性,状态默认绑定的是位置,有 key 时,状态根据key的值绑定到了相应的数组元素上。

之所以加上key是因为vue源码是内部数据驱动,通过改变数据进而达到改变视图,加上key这样算法更容易定位到相应的元素,避免去遍历DOM造成的性能的消耗。


不加 key 的

<div>
  <input type="text" v-model='name'>
  <button @click='add'>添加</button>
</div>
<ul>
  <li v-for='(item, i) in nameList'>
    <input type="checkbox"> {{item.name}}
  </li>
</ul>
</div>
<script>
const HelloVueApp = {
  components: {
    getTitleComponent,
    toDoList
  },
  data() {
    return {
      bookTitle: '',
      selectVal: '',

      nameList: [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' },
        { id: 3, name: '赵武' }
      ],
      name: '',
      newId: 3
    }
  },
  methods: {
    add () {
    	// 注意时 unshift 头加
      this.nameList.unshift({id: ++this.newId, name: this.name})
      this.name = ''
    }
  }
}

Vue.createApp(HelloVueApp).mount('#app')
</script>

在这里插入图片描述
若选中第四个的情况下,再添加一个 刘啊
在这里插入图片描述
原来的赵武变成了李四选中了。

加上 key

<div>
  <input type="text" v-model='name'>
  <button @click='add'>添加</button>
</div>
<ul>
  <li v-for='(item, i) in nameList' :key='item.id'>
    <input type="checkbox"> {{item.name}}
  </li>
</ul>
</div>
<script>
const HelloVueApp = {
  components: {
    getTitleComponent,
    toDoList
  },
  data() {
    return {
      bookTitle: '',
      selectVal: '',

      nameList: [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' },
        { id: 3, name: '赵武' }
      ],
      name: '',
      newId: 3
    }
  },
  methods: {
    add () {
    	// 注意时 unshift 头加
      this.nameList.unshift({id: ++this.newId, name: this.name})
      this.name = ''
    }
  }
}

Vue.createApp(HelloVueApp).mount('#app')
</script>

选中李四,添加吖吖
在这里插入图片描述

在这里插入图片描述

仍旧是李四,这才是我们想要的效果。

文档中

vue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设。
首先讲一下diff算法的处理方法,对操作前后的dom树同一层的节点进行对比,一层一层对比
如图:
在这里插入图片描述
当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。

比如一下这个情况:
在这里插入图片描述
我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:
在这里插入图片描述
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

在这里插入图片描述

vue中列表循环需加:key=“唯一标识” 唯一标识可以是item里面id 等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM。应避免使用 index 或者固定字符串+index。

若后台没有提供 id 等唯一key 值,前端可使用 nanoid 生成id。也可 使用 UUID,但更推荐前者。
npm i nanoid

{id: naniod()}
Logo

前往低代码交流专区

更多推荐