vue摘抄

63 阅读3分钟

Object.defineProperty来劫持整个对象,然后进行深度遍历,给每个属性添加 getter 和 setter,实现响应式,但是存在以下问题:

  • 初始化时需要遍历对象所有key,层级多的情况下,性能有一定影响

  • 动态新增、删除对象属性无法拦截,只能用set/delete api代替

  • 不支持新的Map、Set等数据结构

  • 无法监控到数组下标的变化(监听的性能代价太大) proxy的优势:

  • 可以监听多种操作方法,包括动态新增的属性和删除属性、has、apply等操作

  • 可以监听数组的索引和 length 等属性

  • 懒执行,不需要初始化的时候递归遍历

  • 浏览器新标准,性能更好,并且有持续优化的可能

使用vue渲染大量数据时应该怎么优化?说下你的思路!

  • 可以采取分页的方式获取,避免渲染大量数据

  • [vue-virtual-scroller (opens new window) ]等虚拟滚动方案,只渲染视口范围内的数据

  • 如果不需要更新,可以使用v-once方式只渲染一次

  • 通过[v-memo (opens new window) ]可以缓存结果,结合v-for使用,避免数据变化时不必要的VNode创建

  • 可以采用懒加载方式,在用户需要的时候再加载数据,比如tree组件子树的懒加载

  1. 还是要看具体需求,首先从设计上避免大数据获取和渲染;实在需要这样做可以采用虚表的方式优化渲染;最后优化更新,如果不需要更新可以v-once处理,需要更新可以v-memo进一步优化大数据更新性能。其他可以采用的是交互方式优化,无线滚动、懒加载等方案

Proxy只会代理对象的第一层,那么Vue3又是怎样处理这个问题的呢?

判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。

监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?

我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。

接口请求一般放在哪个生命周期中?

接口请求一般放在mounted中,但需要注意的是服务端渲染时不支持mounted,需要放到created中。

SSR了解

SSR有着更好的SEO、并且首屏加载速度更快等优点。不过它也有一些缺点,比如我们的开发条件会受到限制,服务器端渲染只支持beforeCreatecreated两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。还有就是服务器会有更大的负载需求。

vue的编译流程

  • parse解析阶段:使用正则对template模板进行解析,将标签、指令、属性等转化为AST抽象语法树

  • optimize优化阶段:遍历AST,对静态节点进行标记和提升,优化runtime的性能

  • generate生成阶段:将AST转化为render函数字符串