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方法

  • ```
    patchVnode

    1
    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 算法,都是不进行跨层级比较,只做同级比较

不同点:

  1. vue 会在 patch 函数中给被操作的节点打补丁(patchflag),在 diff 的时候更清晰
  2. vue 对比节点,当节点元素类型相同,但是 className 不同时,认为是不同类型的元素,删除重新创建;而 react 则认为是同类型节点,进行修改操作
  3. diff 策略,vue 的性能优于 react

4、模板编译 template

template->render->h->vdom->true dom

5、vue 组件的渲染和更新流程

初次渲染

更新

完整流程图