二 VUE底层原理
vue 原理
1、mvvm
- M:模型 Model —->也就是 data 中的数据
- V:视图 View —->也就是 dom
- VM:视图模型 ViewModel —->也就是 Vue 实例(vm)
2、vue 响应式原理
核心 api object.defineProperty
vue 响应式也叫作数据双向绑定,大致原理阐述:
首先我们需要通过 Object.defineProperty()方法把数据(data)设置为 getter 和 setter 的访问形式,这样我们就可以在数据被修改时在 setter 方法设置监视修改页面信息,也就是说每当数据被修改,就会触发对应的 set 方法,然后我们可以在 set 方法中去调用操作 dom 的方法。
此外,如果页面有 input 用 v-model 绑定数据,我们需要在这种绑定了 data 的 input 元素上添加监听,添加 input 事件监听,每当 input 事件被触发时,就修改对应的 data
原文链接:https://blog.csdn.net/weixin_48181168/article/details/120158346
vue3 启用 proxy
https://blog.csdn.net/pagnzong/article/details/120389514
代码
proxy 和 object.defineProperty 响应式的对比
vue2 响应式的缺点:
- 检测不到对象属性的添加和删除 (需要使用 vue.set, vue.delete)
- 数组
API
方法无法监听到 (需要特殊处理) - 深度监听需要递归到底,造成性能问题
proxy 解决的问题
- 克服了 vue2 响应式的问题
- 缺点:没有兼容 ie 等其他浏览器,无法实现 polyfill
3、虚拟 dom 和 diff 算法和 react diff 的区别
用 JS 模拟 DOM 结构(vnode)
增量更新: 新旧 vnode 对比,得出最小的更新范围,最后更新 DOM
数据驱动视图的模式下,有效控制 DOM 操作
diff 算法
当数据发生改变时,订阅者
watcher
就会调用patch
给真实的DOM
打补丁通过
isSameVnode
进行判断,相同则调用patchVnode
方法```
patchVnode1
2
3
4
5
6
7
8
9
10
11
做了以下操作:
- 找到对应的真实`dom`,称为`el`
- 如果都有都有文本节点且不相等,将`el`文本节点设置为`Vnode`的文本节点
- 如果`oldVnode`有子节点而`VNode`没有,则删除`el`子节点
- 如果`oldVnode`没有子节点而`VNode`有,则将`VNode`的子节点真实化后添加到`el`
- 如果两者都有子节点,则执行`updateChildren`函数比较子节点
- ```
updateChildren主要做了以下操作:
- 设置新旧
VNode
的头尾指针 - 新旧头尾指针进行比较,循环向中间靠拢,根据情况调用
patchVnode
进行patch
重复流程、调用createElem
创建一个新节点,从哈希表寻找key
一致的VNode
节点再分情况操作
- 设置新旧
相同点:
Vue 和 react 的 diff 算法,都是不进行跨层级比较,只做同级比较
不同点:
- vue 会在 patch 函数中给被操作的节点打补丁(patchflag),在 diff 的时候更清晰
- vue 对比节点,当节点元素类型相同,但是 className 不同时,认为是不同类型的元素,删除重新创建;而 react 则认为是同类型节点,进行修改操作
- diff 策略,vue 的性能优于 react
4、模板编译 template
template->render->h->vdom->true dom
5、vue 组件的渲染和更新流程
初次渲染
更新
完整流程图