vue3新特性:
1) 以es5为基础,更小更快。(快:Proxy重构虚拟dom功能,小:支持tree-shaking,运行时的最小体积将低于10kb)
2) 支持TS 3.0源码使用TS编写(Typescript)
3)优化插槽生成:
在当前的vue版本中,当父组件重新渲染时,其子组件也必须重新渲染(除非修改的数据是子组件的props,才会触发组件的重新渲染)。使用vue3,可以单独重新渲染父组件和子组件。
4) 静态树提升:
使用静态树提升,这意味着vue3的编译器能够检测到什么是静态组件,然后将其提升,从而降低了渲染成本。
5 )更多原生的支持,运行时内核将与平台无关,使得vue可以更容易的与任何平台(ios、android、web)一起使用
6) 更易于开发使用,Observer模块已被解压缩到自己的包中,允许使用它。
7) 3.0 Function-based API 代替传统的Class API ,摒弃高阶组件。
优势:复用简单,把要复用的逻辑抽取到函数中(如mixin)
vue3中重点
1:监测机制
Vue3.0已经放弃了Object.defineProperty ,因为这个实现存在很多限制:
(无法监听属性的添加和删除、数组索引和长度的变更)
而选择了使用更快的原生Proxy:
看一下Proxy对比Object.defineProperty的优势在哪?
它的共同点:这两种都是基于数据劫持实现的双向绑定。
什么是数据劫持?
当访问或者设置对象属性的时候,触发相应的函数,并且返回或者设置的值。劫持对象属性的getter和setter操作,当数据发生变化时发出通知。
数据劫持的优势:
1.不需要进行显示调用,vue的双向绑定原理即使通过数据劫持+发布订阅 来实现的,例如react的setState
2.通过属性的劫持可以精准获得变化的内容,不需要额外的diff操作,减少性能消耗
Object.defineProperty的缺陷:
1)性能:通过遍历对象的属性进行监听,但是属性值也是对象就需要深度遍历。
2)无法监听数组:数组的主要操作场景是遍历,如果每一个元素都挂载set和get方法,会产生巨大性能消耗
3)对属性的添加、删除动作的检测;
4)对数组基于下标的修改、对于 .length修改的检测
重点来了!!!
Proxy的优势:
Proxy可以理解成,在对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写,
可以认为Proxy是Object.defineProperty的全方位加强版!!
1.Proxy可以直接监听对象而非属性,并返回一个新对象。
2.Proxy可以直接监听数组的变化
API: Proxy有多达13种拦截方法,不限于apply、ownKeys、has、deleteProperty等等是Object.defineProperty不具备的。使速度加倍,节省内存开销
常用的api:
–handler.get(target,property,receiver)
用于拦截对象的读取操作,target指目标对象,property指被获取的属性名,receiver是Proxy或者继承Proxy的对象,一般就是Proxy实例。
–handler.set(target,property,value,receiver)
多了个value
–handler.apply(target,thisArg,argumentsList)
用于拦截函数的调用,thisArg指被调用时的上下文对象,argumentsList指调用时的参数数组,此时target必须是一个函数对象,否则会报错
等等。。。
Proxy语法:
1.Proxy是ES6原生提供的
let proxy = new Proxy(target,handler)
参数target使用Proxy包装的目标对象(可以是任何类型的对象,数 组,函数,等)
参数handler也是一个对象,其属性是当执行一个操作时定义代理的行 为函数,也就是自定义的行为。(handler可为空对象且不能为Null)
新的observer 提供了:
1.公开的用于创建observeable的API
2.默认为惰性监测,在2.x版本中,任何响应式的数据,不管它的大小都会在启动的时候监测功能,如果数据量很大的话,在启动应用的时候可能会造成严重的性能消耗。而在3.x中,只有应用的初始可见部分所用到的数据会被检测,大大提升了性能
3.不可变监测对象
4.更好的应用能力,新增的renderTracked和renderTriggered钩子函数,可以精确地追踪到一个组件发生重重渲染的触发时机和完成时机及其原因。
5.更精准的变更通知,在2.x中,你在使用Vue.set来给对象新增一个属性时,这个对象的所有watch都会重新运行;在3.x中,只有依赖的那个属性的watch才会重新执行