- 实现一个监听器 Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者
- 实现一个订阅者 Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图
- 实现一个解析器 Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器
c)
把下面的流程图说清楚就差不多了:
**3. Vue1.x 的设计理念是什么?2.x 的呢?(**58 同城)
Vue1.x 设计理念
- a) 早期 Vue 是采用数据绑定、依赖收集的方式去观察数据变化并保留对实际 DOM 元素的引用,当有数据变化时进行对应的操作。
- b) 少量数据更新对比 Virtual DOM 性能更好,坏处是大量数据更新、初始渲染性能、对比 Virtual DOM 性能更差
- c) 图解:
Vue2.x 设计理念
- Vue2.0 引入了虚拟 dom
- 通过建立虚拟 dom 树, document.createDocumentFragment(),方法创建虚拟 dom 树。一旦被监测的数据改变,会通过 Object.defineProperty 定义的数据拦截,截取到数据的变化。
- 截取到的数据变化,从而通过订阅——发布者模式,触发 Watcher(观察者),从而改
变虚拟 dom 的中的具体数据。
- 最后,通过更新虚拟 dom 的元素值,从而改变最后渲染 dom 树的值,完成双向绑定。
应用篇:
1. Key 的作用是什么?可以用数组的 index(下标)代替么?(美团)
- a) key 的作用主要是为了高效的更新虚拟 DOM。另外 vue 中在使用相同标签 名元素的过渡切换时,也会使用到 key 属性,其目的也是为了让 vue 可以区分它们。否则 vue 只会替换其内部属性而不会触发过渡效果
- b) key 不能用 index 代替,index 在同一个页面会有重复的情况,违背了高效渲染的初衷。
**2. Vue 组件中 data 为什么必须是函数?(**58 同城)
- a) 在 new Vue() , data 是 可 以 作 为 一 个 对 象 进 行 操 作 的 , 然 而 在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它。
- b) 当 data 选项是一个函数的时候,每个实例可以维护一份被返回对象的独立 的拷贝,这样各个实例中的 data 不会相互影响,是独立的。
3. $route 和 $router 的区别是什么?(深信服)
- a) $router 为 VueRouter 的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等。
- b) $route 是路由信息对象||跳转的路由对象,每一个路由都会有一个 route对象,是一个局部对象,包含 path,params,hash,query,fullPath,matched, name 等路由信息参数。
Vue 3.0
A. 响应式优化
1. 为什么要用 Proxy API 替代 defineProperty API?
- a) defineProperty 的局限性的最大原因是它只能针对单例属性做监听,Vue2.x 中对 data 中的属性做了遍历 + 递归,为每个属性设置了 getter、setter。 这也就是为什么 Vue 只能对 data 中预定义过的属性做出响应的原因。
- b) 在Vue 中使用下标的方式直接修改属性的值或者添加一个预先不存在的对 象属性是无法做到 setter 监听的,这是 defineProperty 的局限性。
- c) Proxy 的监听是针对一个对象的,那么对这个对象的所有操作会进入监听 操作,这就完全可以代理所有属性,将会带来很大的性能提升和更优的代 码。
- d) Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访 问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进 行过滤和改写。
2. 响应式是惰性的
- a) 在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它内部深层次的 变化,就需要递归遍历这个对象,执行 Object.defineProperty 把每一层对 象数据都变成响应式的,这无疑会有很大的性能消耗。
- b) 在 Vue.js 3.0 中,使用 Proxy API 并不能监听到对象内部深层次的属性变 化,因此它的处理方式是在 getter 中去递归响应式,这样的好处是真正 访问到的内部属性才会变成响应式,简单的可以说是按需实现响应式,减少性能消耗。
- c)Proxy 基础用法:
B. 编译优化
3. Vue3.0 编译做了哪些优化?
a)
生成
block tree
- Vue.js 2.x 的数据更新并触发重新渲染的粒度是组件级的,单个组件内部 需要遍历该组件的整个 vnode 树。
- Vue.js 3.0 做到了通过编译阶段对静态模板的分析,编译生成了 Block tree。Block tree 是一个将模版基于动态节点指令切割的嵌套区块,每个 区块内部的节点结构是固定的。每个区块只需要追踪自身包含的动态节 点。
3.1 传统 Virtual DOM 的性能瓶颈
3.1.1 根本原因
3.1.2 优化(动静结合)