讓列表渲染不再重複!用 Lodash 的 uniqueId 解決 Vue 的 key 衝突


技術紀錄

今天在處理一個 Vue 專案時,遇到一個頗讓人頭大的問題。在列表渲染中,v-forkey 屬性出現了問題:當畫面上有多個數據動態渲染時,會出現 Vue 警告 Duplicate keys detected,導致某些畫面行為怪怪的,例如刪除項目後其他項目跟著亂動。

問題情境

畫面上有一堆動態生成的標籤 (tag),每個標籤代表一個數字,從一個字串轉換過來,例如 "1,2,3" 變成三個標籤。但當我用 :key="number" 時,Vue 無法保證這些 key 的唯一性,因為數字本身可能重複。例如 1,2,3,3,會讓 key 的值產生衝突。

看起來很小的問題,實際卻很嚴重。如果 key 重複了,Vue 的虛擬 DOM 會搞不清楚哪些元素需要重新渲染,結果畫面可能完全錯亂。

解決方式

最簡單的解法就是給每個標籤加一個真正唯一的 key。這時候,Lodash 的 uniqueId 就派上用場了,它可以根據給定的前綴自動生成唯一 ID:

<template>
  <div>
    <a-tag
      v-for="number in numbers"
      :key="uniqueId(number)"
      class="ticket-result"
    >
      {{ number }}
    </a-tag>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { uniqueId } from 'lodash-es';

const numbers = ref(['1', '2', '3', '3']);
</script>

我們用 uniqueId 為每個數字生成一個獨特的 key,例如 1_12_23_3,即使數字重複,也能避免 Vue 發生 key 衝突。

背後的思考

一開始覺得這問題挺「無聊」的,後來發現它是 Vue 效率優化的核心邏輯之一。key 就像 Vue 虛擬 DOM 的「身份證」,如果 key 重複了,Vue 的「大腦」會無法辨認哪些元素應該更新、移除或保持原樣。

所以無論是這種列表渲染,還是更複雜的動態表單,保證 key 的唯一性都非常重要。用 uniqueId 這種簡單又直覺的方法,真的可以讓開發效率提升很多。