# 1. Vue3
# 1. Vue3 的新特性
a. setup() 函数是 vue3 中,专门为组件提供的新属性。它为我们使用 vue3 的 Composition API 新特性提供了统一的入口,setup 函数会在 beforeCreate 之前执行。
setup(props, context) {
context.attrs
context.slots
context.parent
context.root
context.emit
context.refs
}
b.响应式由 Object.definePropety 改为 Proxy
c.新的 API,reactive、ref、isRef、toRefs、computed、watch
d.生命周期只能用在setup函数中
e.新的标签Fragment/Suspense/Teleport
# 2. Vue3 中 ref reactive toRefs 的区别及作用。 具体见 composition-api
Vue3 的computed返回为为ref,是为了防止基本类型的数据丢失响应式。
JavaScript 中区别声明基础类型变量与对象变量时一样区别使用 ref 和 reactive,使用 reactive 的问题是,使用组合函数时必须始终保持对这个所返回对象的引用以保持响应性,这个对象不能被解构或展开。toRefs API 用来提供解决此约束的办法,它将响应式对象的每个 property 都转成了相应的 ref。
# 3. Vue3 的初始化过程
createApp(App).mount(rootNode)
Vue3初始化的过程从调用 mount 方法开始,
- 调用
mount方法后,基于根组件、根节点创建vnode,vnode创建完成后开始render渲染,render实际调用的是patch方法 - 在
patch方法中,根据shapeFlag来判断是初始化component还是element - 先是初始化
component,初始化component分为三步,一是通过createComponentInstance创建组件实例,二是调用setupComponent来配置组件,这里主要实现initProps/initSlots/配置 setup/配置 render 方法,三是setupRenderEffect,这里调用上一步的render方法来生成子组件的vnode,触发自身的beforeMount,递归调用patch方法来初始化子元素,最后触发mounted - 初始化
component最后一步的setupRenderEffect中递归调用patch处理子元素,patch的子元素有component和element类型。如果是component类型,会重复上面第三步进行初始化,这也是生命周期父 beforeMount->子 beforeMount->子 mounted->父 mounted的原因。如果子元素是element类型,会进行以下处理:调用createElement方法来创建真实 element,处理children节点,调用hostPatchProp处理标签上的属性,触发beforeMount钩子,调用insert插入父节点,最后触发mounted。
# 4. Vue2 的 Object.defineProperty 和 Vue3 的 Proxy 对比
Object.defineProperty的缺点:
无法检测到对象属性的新增或删除
由于 js 的动态性,可以为对象追加新的属性或者删除其中某个属性,这点对经过
Object.defineProperty方法建立的响应式对象来说,只能追踪对象已有数据是否被修改,无法追踪新增属性和删除属性,这就需要额外的代码处理。数组变化监听:vue2.x 是通过代理数组原型,包装了一层数组的变异方法:
'pop','shift','unshift','sort','reverse','splice', 'push'get set 拦截器不能直接操作 target 对象
Vue3 的 Proxy 代理是针对整个对象,不是针对对象属性做拦截,替换了原先遍历对象使用Object.defineProperty方法给属性添加 set,get 访问器的笨拙做法,优化性能
劣势:
- 性能比 promise 还差
- 兼容性不太乐观 ,无法完全 polyfill
2. 实战 →