看了react
和vue
官方文档关于keys
的介绍, 感觉它们是互通的, 写了个可以删除单项的todoList
,并有动画效果的demo
, 通过这个demo
加深了对keys
的理解.
vue
提供了内置组件 transition-group
, demo
利用这个组件实现进入/离开的列表
, 而keys
在transition-group
中有着很重要的作用, 使用不当, 影响性能, 动画无效, 或者动画会和预期不一致. 围绕keys
的介绍, vue
和react
文档感觉差不多, 如果结合下面使用react
中的文档理论介绍, 说明vue demo
, 那就多少可以说明一部分它们是互通的.
Keys Must Only Be Unique Among Siblings
首先列表中的item
项必须有个唯一的标识key
, 通常我们会使用api
提供数组数据中的item.id
, 如果列表数据中, 不确定有唯一标识, 可以使用index
, 但并不推荐, 如下:
function Blog(props) {
const sidebar = (
<ul>
{props.posts.map((post, index) =>
<li key={post.id}>
{post.title}
</li>
)}
</ul>
);
todoList
的demo
已经完成, 输入文本确定后, 文本会有个过渡动画进入列表, 点击删除, 文本会有个过渡动画离开列表, 因为使用了vue
中内置组件transition-group
, demo变更简单.
当我使用index
作为key
时, 没有任何警告, 但点击删除时, 动画和预期不一致, 被删除的直接离开了列表, 没有任何过渡, 而另一处的文本出现了动画,但没被删除(这里删除逻辑是没有错误的). 于是修改了key
为item.id
, 一切和预期一致.
As a last resort, you can pass an item’s index in the array as a key. This can work well if the items are never reordered, but reorders will be slow. Reorders can also cause issues with component state when indexes are used as keys. Component instances are updated and reused based on their key. If the key is an index, moving an item changes it. As a result, component state for things like uncontrolled inputs can get mixed up and updated in unexpected ways.
引用了react
文档中的2段文字, 说的是如果你的列表没有重新排序, index是没有问题的, 但如果列表有重新排序的操作, 就可能引起一些问题, 组件状态可能失控
这就是为什么上面item.id
是推荐写法, 但通过这个demo
, 会知道到底是用item.id
还是index
, 这个可以根据具体列表情况去使用, 如果列表顺序没有改变的操作, 用index
也很方便.