Vue模板中传递对象或数组时,避免直接使用字面量[]和{}
在 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" />
通过保持对象/数组的引用稳定,可显著优化子组件渲染性能,避免因父组件更新导致的无效重渲染。