刷刷题37(vue3的优化点)

1. ‌Vue3 响应式原理中,Proxy 和 Reflect 是如何配合使用的?为何要结合 Reflect?

  • Proxy ‌ 用于拦截对象操作(如 getsetdeleteProperty),‌Reflect ‌ 提供默认行为的方法(如 Reflect.get)。
  • 配合方式 ‌:在 Proxy 的 get/set 等陷阱中,通过 Reflect 执行原始操作,确保代理对象行为与原始对象一致。
javascript 复制代码
const proxy = new Proxy(target, {
  get(target, key, receiver) {
    track(target, key); // 依赖收集
    return Reflect.get(target, key, receiver); // 保持 this 正确指向
  },
  set(target, key, value, receiver) {
    trigger(target, key); // 触发更新
    return Reflect.set(target, key, value, receiver);
  }
});
  • 为何用 Reflect‌:

    • 避免直接操作目标对象导致 this 指向错误(例如访问对象方法时,this 应指向代理对象而非原对象)。
    • 兼容性更好,Reflect 方法返回布尔值(如 Reflect.set 返回是否设置成功),方便错误处理。

2. ‌Vue3 的"静态节点提升"和"PatchFlag"如何优化 diff 算法?

  • 静态节点提升(Static Node Hoisting) ‌:

    • 编译阶段将静态节点(无动态绑定的元素)提取到渲染函数外,生成一次后复用,避免 diff 时重复比较。
  • PatchFlag‌:

    • 在编译时为动态节点添加标记(如 1 表示文本动态,8 表示 props 动态),diff 时仅对比带标记的部分。
  • 协同优化‌:

    • 静态节点直接跳过 diff,动态节点通过 PatchFlag 缩小对比范围,整体复杂度从 O(n) 降低到接近 O(1) 的动态部分。

3. ‌如何实现 Vue 自定义渲染器(如渲染到 Canvas)?

步骤‌:

  1. 使用 createRenderer 创建渲染器,提供自定义的 createElementpatchPropinsert 等方法:
typescript 复制代码
const { createRenderer } = Vue;
const renderer = createRenderer({
  createElement(type) { /* 创建 Canvas 元素 */ },
  patchProp(el, key, prev, next) { /* 更新属性 */ },
  insert(el, parent) { /* 插入到 Canvas 层级 */ }
});

在组件中使用 renderer.createApp 替代默认的 createApp

ini 复制代码
const app = renderer.createApp(RootComponent);
app.mount('#canvas-container');
  1. 实现 Canvas 渲染逻辑:

    • requestAnimationFrame 批量更新,避免频繁重绘。
    • 将虚拟节点映射为 Canvas 的绘制指令(如 drawRectdrawText)。

4. ‌Composition API 中如何避免"响应式数据滥用"?

  • 合理选择 API‌:

    • reactive:深响应式对象,适合复杂数据结构(如嵌套对象)。
    • ref:包装基本类型,通过 .value 访问,适用于独立值。
    • shallowRef/shallowReactive:浅层响应式,避免深层递归带来的性能损耗。
  • 优化场景‌:

    • 大数组或只读数据:使用 shallowRefmarkRaw 跳过代理。
    • 频繁更新的数据:使用 ref 替代 reactive,减少 Proxy 层级。

5. ‌高性能长列表滚动加载如何结合 Vue 和 Intersection Observer?

‌ ‌关键思路‌:

  1. 虚拟列表 ‌:仅渲染可见区域的 DOM 元素,通过 transform 偏移模拟滚动。
  2. Intersection Observer‌ 监听元素是否进入视口,动态加载数据:
scss 复制代码
const observer = new IntersectionObserver((entries) => {
  if (entries.isIntersecting) {
    loadMore(); // 加载下一页数据
  }
});
observer.observe(loaderRef.value); // 监听"加载更多"元素
  1. 响应式优化‌:

    • 使用 shallowRef 存储列表数据,避免深响应式开销。
    • v-memo(Vue3.2+)缓存已渲染的列表项,避免重复渲染。

5. ‌Vue3 中 v-model 的自定义实现及 .sync 替代方案

  • v-model 原理‌:

    • 默认绑定 modelValue prop 和 update:modelValue 事件。
xml 复制代码
<!-- 自定义组件 -->
<Child :modelValue="value" @update:modelValue="value = $event" />

等价语法‌:

vbnet 复制代码
// 组件内部
props: ['modelValue'],
emits: ['update:modelValue']

替代 .sync‌:

  • Vue3 移除了 .sync,改用 v-model:propName
xml 复制代码
<Child :title="pageTitle" @update:title="pageTitle = $event" />
<!-- 简写为 -->
<Child v-model:title="pageTitle" />
相关推荐
yechaoa1 分钟前
【揭秘大厂】技术专项落地全流程
android·前端·后端
MurphyChen7 分钟前
🤯 一行代码,优雅的终结 React Context 嵌套地狱!
前端·react.js
逛逛GitHub12 分钟前
推荐 10 个受欢迎的 OCR 开源项目
前端·后端·github
ylfhpy22 分钟前
Java面试黄金宝典1
java·开发语言·算法·面试·职场和发展
_xaboy39 分钟前
开源 FormCreate 表单设计器配置组件的多语言
前端·vue.js·低代码·开源·可视化表单设计器
uglyduckling04121 小时前
小程序构建NPM失败
前端·小程序·npm
草原上唱山歌1 小时前
C/C++都有哪些开源的Web框架?
前端·c++·开源
烛阴1 小时前
JavaScript 调度:setTimeout 和 setInterval
前端·javascript
難釋懷1 小时前
JavaScript基础-获取元素
开发语言·javascript
月巴月巴白勺合鸟月半1 小时前
工作记录 2017-02-03
前端·c#·健康医疗