在 Vue 中,直接在模板中使用 []
或 {}
作為 prop 值會導致子組件不必要的重新渲染,因為每次父組件渲染時都會創建新的引用。以下是解決方案和最佳實踐:
1. 避免在模板中直接使用字面量
<!-- 避免這樣寫 -->
<ChildComponent :items="[]" :config="{}" />
2. 使用 data
或 computed
定義引用
將空數組/對象定義在父組件的 data
中,保持引用穩定:
export default {data() {return {// 保持引用不變的空數組/對象emptyArray: Object.freeze([]), emptyObject: Object.freeze({})}}
}
<ChildComponent :items="emptyArray" :config="emptyObject" />
3. 使用 Object.freeze
(推薦)
凍結對象防止 Vue 添加響應式,同時保持引用不變:
data() {return {staticArray: Object.freeze([]), // 不可變空數組staticObject: Object.freeze({}) // 不可變空對象}
}
4. 常量共享引用(跨組件復用)
// constants.js
export const EMPTY_ARRAY = Object.freeze([]);
export const EMPTY_OBJ = Object.freeze({});// 父組件
import { EMPTY_ARRAY, EMPTY_OBJ } from './constants';export default {data() {return {emptyArray: EMPTY_ARRAY,emptyObject: EMPTY_OBJ}}
}
5. 需要響應式數據時
如果數據需要變動但初始值需為空,使用標準響應式定義:
data() {return {items: [], // 響應式可修改數組config: {} // 響應式可修改對象}
}
關鍵點說明
方案 | 引用穩定性 | 是否響應式 | 適用場景 |
---|---|---|---|
模板字面量 [] /{} | ? 每次變 | ? 無 | 不推薦 |
data + Object.freeze | ? 穩定 | ? 凍結 | 靜態空值 |
共享常量 | ? 穩定 | ? 凍結 | 跨組件復用空值 |
普通 data 屬性 | ? 穩定 | ? 響應式 | 需要修改的動態數據 |
附加建議
- 對于純展示型子組件,使用
v-once
避免重渲染:<ChildComponent v-once :config="staticObject" />
- 復雜場景使用
v-memo
(Vue 3.2+):<ChildComponent v-memo="[someKey]":items="items" />
通過保持對象/數組的引用穩定,可顯著優化子組件渲染性能,避免因父組件更新導致的無效重渲染。