1、Vue 3.0 性能提升主要是通过哪几方面体现的?
- 响应式系统升级:
Vue2.0是在数据初始化之后,遍历对象的属性通过Object.defineProperty监听属性的变化。vue3.0采用Proxy代理对象拦截对象的访问,可以监听动态新增的属性、删除的属性、数组的索引和length属性。
- 编译优化:
Vue2.0中渲染的最小单位是组件,会标记静态根节点,优化diff的过程,但静态节点还要通过diff。Vue2.0中会标记所有的静态节点,diff的过程只需要对比动态节点内容。
Fragments(片段):组件内支持多个同级的根标签
- 静态提升:标签中仅仅是纯文本的节点,会提升到
render函数外,再次render无须再次创建
- Patch flag: 标记不同类型的节点(如动态文本节点、有动态属性的节点),优化
diff的过程
- 缓存事件处理函数、组件按需动态导入
- 源码体积优化
Vue3.0中移除了一些不常用API,如:inline-template、filter
Tree-shaking(依赖ESmodule的模块化规范)
2、Vue 3.0 所采用的 Composition Api 与 Vue 2.x使用的Options Api 有什么区别?
Vue2.0中的Options API包含描述组件选项(data、methods等)的对象,在描述复杂组件时,同一功能的逻辑被拆分到不同的选项中,随着版本的迭代难以维护
Vue3.0中的Compositon API新增一组基于函数的API,可以更加灵活的组织同一个功能的代码片段
Vue3.0中的setup(props, context){}在实例被初始化之前执行,故在setup中的this上没有任何东西
3、Proxy 相对于 Object.defineProperty 有哪些优点?
Proxy直接监听对象而非属性,有多达13种拦截方法,如 apply、ownKeys、has 等等,这是Object.defineProperty不具备的
- 多层属性嵌套,在访问属性过程中处理下一级属性
- 默认监听动态添加的属性
- 默认监听属性的删除操作
- 默认监听数组索引和
length属性
4、Vue 3.0 在编译方面有哪些优化?
Vue2.0中渲染的最小单位是组件,会标记静态根节点,优化diff的过程,但静态节点还要通过diff。Vue2.0中会标记所有的静态节点,diff的过程只需要对比动态节点内容。
Fragments(片段):组件内支持多个同级的根标签
- 静态提升:标签中仅仅是纯文本的节点,会提升到
render函数外,再次render无须再次创建
- Patch flag: 标记不同类型的节点(如动态文本节点、有动态属性的节点),优化
diff的过程
- 缓存事件处理函数、组件按需动态导入
5、Vue.js 3.0 响应式系统的实现原理?
Vue3.0使用Proxy对象重写响应式系统
Proxy代理拦截:
reactive函数执行,会将传入的target对象通过Proxy包装,拦截它的get,set等,并将代理的target缓存到targetMap,targetMap.set(target, new Map())。
代理的get的时候会调用一个track函数,而set会调用一个triger函数。分别对应依赖收集和触发更新。
export function reactive (target) {
if (!isObject(target)) return target
const handler = {
get (target, key, receiver) {
track(target, key)
const result = Reflect.get(target, key, receiver)
return convert(result)
},
set (target, key, value, receiver) {
const oldValue = Reflect.get(target, key, receiver)
let result = true
if (oldValue !== value) {
result = Reflect.set(target, key, value, receiver)
trigger(target, key)
}
return result
},
deleteProperty (target, key) {
const hadKey = hasOwn(target, key)
const result = Reflect.deleteProperty(target, key)
if (hadKey && result) {
trigger(target, key)
}
return result
}
}
return new Proxy(target, handler)
- 依赖收集和触发更新:
- 组件在
render阶段,视图会读取数据对象上的值进行渲染,此时便触发了Proxy的get,由此触发对应的track函数,记录下了对应的ReactiveEffect,也就是依赖收集。
ReactiveEffect其实就可以看作是组件的更新(mount是特殊的update),数据的变更触发trigger,trigger遍历调用track收集的对应的数据的ReactiveEffect,也就是对应有关联的组件的更新。trigger触发的组件的更新,在render阶段又触发了新一轮的track依赖收集,更新依赖