刷刷题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" />
相关推荐
kyriewen43 分钟前
Git Commit 前自动修复代码风格?配置 Husky + lint-staged,从此 CR 只聊逻辑
前端·git·面试
小和尚同志1 小时前
AI 自动化测试探索(一):Playwright MCP
前端·人工智能·aigc
程序员二叉1 小时前
【JUC】ThreadLocal底层原理|内存泄漏|弱引用|跨线程传递方案
java·开发语言·面试·职场和发展·juc
程序员二叉1 小时前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
老马识途2.01 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
徐小夕2 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
运筹vivo@2 小时前
Python ContextVar 底层机制与内存模型拆解
前端·数据库·python
#麻辣小龙虾#3 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar3 小时前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github
weixin_471383034 小时前
Taro-02-页面路由
前端·taro