众所周知,在Vue中是不推荐使用index
作为列表循环的key来绑定的,原因可见这篇文章 -> 在 Vue 中为什么不推荐用 index 做 key
那么,当我们遇到不得不避免使用index
作为key
,但同时后端传来的数据中又没有唯一标识字段的时候怎么办呢?
办法就是自己为数据添加唯一标识 —— uuid
(Universally Unique Identifier),当然这需要引入一个第三方库 -> uuid
代码如下(核心就是bindWithKey
函数):
<template>
<h3>{{ name }}</h3>
<div v-for="{ it, key } in list" :key="key">{{ it }} <input type="text" /></div>
<button @click="insert">插入一行</button>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import { v4 as uuidv4 } from 'uuid';
function bindWithKey<T>(arr: Array<T>): { it: T; key: string }[];
function bindWithKey<T>(arr: T): { it: T; key: string };
function bindWithKey(arr: Array<unknown> | string | number) {
return typeof arr === 'object' ? arr.map((v) => ({ it: v, key: uuidv4() })) : { it: arr, key: uuidv4() };
}
const list = reactive(bindWithKey(['haha', 'heihei', 'hehe']));
const insert = () => {
list.unshift(bindWithKey('hiahia'));
};
</script>
可以看出,这样的做法会消耗一定的性能,但是如果情况所迫,比如数据量很大但偏偏需要频繁逆序插入数据,或者出现了diff
算法导致的数据错位不太能轻易解决的时候,那么可以考虑下本文的解决方案。
另外,虽然Vue建议采用唯一标识作为key
来绑定,但是一般情况下使用index
作为key
是不会有什么问题的,根据具体情况来决定吧