刷刷题37(vue3的优化点)

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

  • ‌Proxy ‌ 用于拦截对象操作(如 get、set、deleteProperty),‌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 创建渲染器,提供自定义的 createElement、patchProp、insert 等方法:
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 的绘制指令(如 drawRect、drawText)。

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

‌

  • ‌合理选择 API‌:

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

    • 大数组或只读数据:使用 shallowRef 或 markRaw 跳过代理。
    • 频繁更新的数据:使用 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" />
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
晨米酱3 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄3 天前
JavaScript 隐式全局变量解析
javascript
彧azz3 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端