vue v-for
当你使用 v-for
指令来渲染列表时,为每个元素提供一个唯一的 key
属性是非常重要的。key
是用来给 Vue 一个提示,以便它能够追踪每个节点的身份,从而更高效地更新虚拟 DOM。
key
的作用
-
唯一标识 :
key
应该是每项数据的唯一标识符,这样 Vue 可以区分不同的元素。通常可以使用数据项中的唯一 ID 或者数组索引(虽然不推荐)作为key
。 -
优化更新性能 :当数据发生变化时,Vue 使用
key
来识别哪些元素被添加、删除或重新排序,从而最小化组件的重渲染范围,提高性能。 -
保持组件状态 :如果列表中的元素是动态组件或包含可输入的表单元素(如
<input>
),key
可以帮助保留用户的输入状态。没有key
,Vue 可能会复用元素,导致意外的状态丢失。
基本用法
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
在这个例子中,假设 items
是一个对象数组,每个对象都有一个唯一的 id
和 name
属性。:key="item.id"
确保了每个 <li>
元素都有一个唯一的键值,这有助于 Vue 更高效地管理这些元素。
注意事项
-
避免使用数组索引作为
key
:尽管可以使用数组的索引作为key
,但这是不推荐的做法,尤其是在列表顺序可能会变化的情况下。因为这样做会导致 Vue 无法准确地跟踪元素的身份,进而可能导致不必要的重渲染或其他问题。<!-- 不推荐 --> <div v-for="(item, index) in items" :key="index"> {{ item.name }} </div>
-
确保
key
的唯一性 :key
必须是唯一的,这意味着在一个v-for
循环内部,所有的key
都应该是独一无二的。重复的key
可能会导致不可预知的行为。
状态错误例子:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>Vue 2 Todo App</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="(todo, index) in todos" :key="index">
<input type="checkbox">
{{ todo.text }}
<button @click="removeTodo(index)">Remove</button>
</li>
</ul>
<input v-model="newTodoText" placeholder="Add a new todo">
<button @click="addTodo">Add Todo</button>
</div>
<script>
new Vue({
el: '#app',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
{ text: 'Build something awesome' }
],
newTodoText: ''
},
methods: {
addTodo() {
this.todos.push({ text: this.newTodoText });
this.newTodoText = '';
},
removeTodo(index) {
this.todos.splice(index, 1);
}
}
});
</script>
</body>
</html>

点击删除第一个.对应的效果

-
旧的 VNode 列表 (删除前):
key: 0
-> 对应数据{ id: 1, ... }
key: 1
-> 对应数据{ id: 2, ... }
key: 2
-> 对应数据{ id: 3, ... }
-
新的 VNode 列表 (删除后):
key: 0
-> 对应数据{ id: 2, ... }
(注意:索引0现在对应的是原来索引1的数据)key: 1
-> 对应数据{ id: 3, ... }
(注意:索引1现在对应的是原来索引2的数据)
vue会认为key值相同的是同一个元素,不会进行删除,而是会用更新的状态,去改变更改的内容.
也就是key0的节点和key1的节点有对应项.进行了更新
对应到key2的最后一项.新vnove里没有该项.会删除最后一项. 导致删除的不是第一项出现了状态的丢失
指令修饰符

指令修饰符(Modifiers) 是一种特殊后缀,以点符号(.
)开头,用于指出一个指令应当以特殊的方式来绑定。它们可以简化代码,并且使意图更加明确。
下面是一些常用的 Vue 指令及其修饰符的详细解释:
1. v-model
修饰符
-
.lazy
: 默认情况下,v-model
在每次input
事件触发后将输入框的值与数据进行同步。使用.lazy
修饰符则改为在change
事件之后进行同步。<!-- 在"change"时而非"input"时更新 --> <input v-model.lazy="message">
-
.number
: 自动将用户的输入值转换为数值类型。如果输入内容不能被转换为数字,则返回原始的输入值。<input v-model.number="age" type="number">
-
.trim
: 自动过滤用户输入的首尾空格。<input v-model.trim="msg">
2. v-on
(或 @
) 修饰符
-
.stop
: 调用event.stopPropagation()
方法,阻止事件冒泡。<div @click="doSomething"> <button @click.stop="doSomethingElse">Stop Propagation</button> </div>
-
.prevent
: 调用event.preventDefault()
方法,阻止默认行为。<form @submit.prevent="onSubmit"></form>
-
.capture
: 使用事件捕获模式添加事件监听器。<div @click.capture="doSomething">Capture!</div>
-
.self
: 只当事件是从侦听器绑定的元素本身触发时才触发回调。<div @click.self="doSomething">Self Click</div>
-
.once
: 点击事件只会触发一次。<button @click.once="doThis">Only once</button>
-
.passive
: 告诉浏览器你不想阻止事件的默认行为(主要用于优化滚动性能)。例如,在处理触摸或滚轮事件时非常有用。<div @scroll.passive="onScroll">...</div>
3.常用按键修饰符
-
.enter
: 监听 Enter 键。<input @keyup.enter="submit">
-
.tab
: 监听 Tab 键。<input @keydown.tab="onTab">
-
.delete
: 监听 Delete 和 Backspace 键。<input @keydown.delete="onDelete">
-
.esc
: 监听 Escape 键。<input @keyup.esc="closeModal">
-
.space
: 监听 Space 键。<input @keydown.space="onSpace">
-
.up
: 监听 Up 键。<input @keydown.up="onUp">
-
.down
: 监听 Down 键。<input @keydown.down="onDown">
-
.left
: 监听 Left 键。<input @keydown.left="onLeft">
-
.right
: 监听 Right 键。<input @keydown.right="onRight">
-
.ctrl
: 监听 Ctrl 键。<input @keydown.ctrl.enter="save">
-
.alt
: 监听 Alt 键。<input @keydown.alt.enter="submit">
-
.shift
: 监听 Shift 键。<input @keydown.shift.enter="insertLineBreak">
-
.meta
: 监听 Meta 键(在 Mac 上通常是 Command 键,在 Windows 上是 Windows 键)。<input @keydown.meta.enter="openMenu">
总结
Vue 的指令修饰符极大地增强了 Vue 指令的功能性,使得我们可以更加简洁和直观地处理常见的交互逻辑,如表单验证、事件控制等。理解并正确使用这些修饰符可以使你的代码更加清晰易懂,同时也能提高开发效率。对于特定场景下的需求,比如需要阻止事件冒泡或者确保输入值为数字类型等,合理利用修饰符可以让你的代码更加健壮和易于维护。