1、双向数据绑定-响应式原理不同
vue2是利用ES5的Object.defineProperty()进行数据劫持、发布-订阅来实现的。(监听者监听到数据发生变化之后,通知所有订阅者,相应的订阅者根据数据变化渲染到对应视图上)
【拓展】:发布-订阅者模式主要有下面几个概念:
- Publisher :发布者,当消息发生时负责通知对应订阅者
- Subscriber :订阅者,当消息发生时被通知的对象
- SubscriberMap :持有不同 type 的数组,存储有所有订阅者的数组
- type :消息类型,订阅者可以订阅的不同消息类型
- subscribe :该方法为将订阅者添加到 SubscriberMap 中对应的数组中
- unSubscribe :该方法为在 SubscriberMap 中删除订阅者
- notify :该方法遍历通知 SubscriberMap 中对应 type 的每个订阅者
vue3是利用ES6的proxy代理来实现的。(proxy相当于一个拦截作用,不能直接访问对象,要经过proxy访问)
【拓展】:改为proxy的原因,或者说proxy相对于defineProperty() 的优势。
- 支持新的Map、Set等数据结构
- 同时支持object、array
- 动态属性增、删都可以拦截
- 对象嵌套属性运行时递归,用到才代理
2、vue3支持碎片化
(碎片化可以理解为,template内可以不是一个根dom,允许有多个根)
vue2
中组件确实只能有一个根,但vue3
中组件已经可以多根节点了。- 之所以需要这样是因为
vdom
是一颗单根树形结构,patch
方法在遍历的时候从根节点开始遍历,它要求只有一个根节点。组件也会转换为一个vdom
,自然应该满足这个要求。vue3
中之所以可以写多个根节点,是因为引入了Fragment
的概念,这是一个抽象的节点,如果发现组件是多根的,就创建一个Fragment节点,把多个根节点作为它的children。将来patch的时候,如果发现是一个Fragment节点,则直接遍历children创建或更新。
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<div> vue3 允许存在多个根</div>
</template>
3、生命周期不同
vue2生命周期 | vue3生命周期 | 描述 |
beforeCreate | beforeCreate | 组件创建前 |
created | created | 组件创建后 |
beforeMount | beforeMount | 挂载前 |
mounted | mounted | 挂载后 |
beforeUpdate | beforeUpdate | 更新前 |
updated | updated | 更新后 |
beforeDestroy | beforeUnmount | 销毁前 |
destroyed | unmounted | 销毁后 |
activated | activated | keep-live缓存组件激活时 |
deactivated | deactivated | keep-live缓存组件停用时 |
errorCaptured | errorCaptured | 捕获一个来自子孙组件的错误时被调用 |
- | renderTracked | 调试钩子,响应式依赖被收集时调用 |
- | renderTriggered | 调试钩子,响应式依赖被触发时调用 |
- | serverPrefetch | ssr only,组件实例在服务器上被渲染之前 |
4、数据和方法的定义不同
vue2是选项式API,分成了data,methods,computed...等属性
vue3是组合式API,只有setup()一个入口函数,大大提升了代码的整洁性和可读性
----------------------------------------------------------------------------------------------------------------------------
记录学习成长过程,如有不足欢迎指正~