大批量数据传 Props 易致卡顿,应采用轻量可控方案:①用 Object.freeze 或 markRaw 跳过响应式;②分片加载+虚拟滚动替代全量渲染;③provide/inject 替代深层透传;④异步加载+懒初始化优化性能。

大批量数据通过 Props 传递到 Vue 组件时,容易触发频繁的响应式追踪、虚拟 DOM 对比和渲染,造成卡顿甚至页面冻结。关键不是“能不能传”,而是“怎么传更轻量、更可控”。
用 Object.freeze 或 markRaw 跳过响应式劫持
如果子组件只读取大数据(如列表、配置项),不修改它,就无需让 Vue 追踪变化:
-
Vue 2:在父组件中用
Object.freeze(largeData)后再传入 Props,避免递归 defineProperty; -
Vue 3:配合
markRaw()(需在setup中调用)或直接传入已冻结对象,阻止 reactive 转换; - 注意:冻结后子组件也无法
reactive或ref包裹它,适合纯展示场景。
分片加载 + 虚拟滚动替代全量渲染
真正卡顿往往来自一次性渲染几千个 DOM 节点。Props 可以传全量数据,但渲染必须节制:
Element Plus Vue3 桌面组件库。在开发 Vue 3.x 页面时调用,使用 Element Plus 组件(如 el-button、el-input、el-form、el-table 等)。
- 用
v-for渲染前,先通过computed或useMemo-类逻辑做分页/切片(如每次只取 50 条); - 集成
vue-virtual-scroller或virtuoso等虚拟滚动库,DOM 节点数恒定,滚动时动态更新可见区域数据; - Props 仍可接收完整数据,但子组件内部只暴露“当前视窗数据”给模板,避免 diff 全量。
用 provide / inject 替代深层 Props 透传
当大数据需跨多层组件使用(如表格列配置、全局筛选条件),逐层 Props 会加重响应式开销和代码冗余:
立即学习“前端免费学习笔记(深入)”;
- 父组件用
provide({ largeConfig: markRaw(config) })注入; - 任意深层子组件
inject获取,不经过中间组件的 props 声明与响应式处理; - 相比层层传递,减少 proxy 创建、依赖收集和更新通知链路,尤其适合静态或低频变更的大对象。
异步加载 + 懒初始化数据结构
不要在组件创建时就处理大数据,把耗时操作延后或拆解:
- 用
onMounted或nextTick延迟执行数据预处理(如构建索引、分组 map); - 对搜索/排序等操作,用
computed+ 缓存(lodash.memoize或自建 Map 缓存键值),避免重复计算; - 必要时将大数据存在
ref(null),首次访问时再用Promise异步解析并缓存结果,首屏不阻塞。

















