关于整体流程的补充:

来源:4-19 vue组件是如何渲染和更新的

fy000

2020-03-06

看见一些老铁对于 何时更新 何时收集、何时render在提问区有些问题,因为老师这门课讲原理,不可能对各个方面都涉及,可能没有看过源码的人会懵一些, 因为源码包含全部的细节,对大家比较迷惑的部分从头写一下,也当作自己的一次回顾:如有不对的地方,欢迎指出

1. new Vue
代码中 const vm = new Vue(),实际触发了_init函数,定义如下(只保留关键步骤):

Vue.prototype._init = function () {
    initLifecycle(vm)
     //...各种init:Events、Hook(beforeCreate、created)
    initState(vm);                 //★ 重点
    ...
    vm.$mount(vm.$options.el)     //★ 重点
    }

其中initState 就是对 props、data等进行双向数据绑定,绑定get set 函数

2.mount (template->render)
mount就是挂载, 在init各种 之后,进行$mount
第一步:先将template->render 编译
第二步: 创建渲染Watcher

updateComponent = () => {
      vm._update(vm._render(), hydrating)
 },
new Watcher(vm, updateComponent,...)  //负责整个dom渲染的watcher 重点

在这个watcher 内 会读取dom中用到的数据,也就触发了上面双向绑定的get,get内部进行依赖收集:

    get: function reactiveGetter() {
       //...
        dep.depend(watcher)  //watcher  Dep.target 当前watcher
        return value
    },
    set: function reactiveSetter(newVal) {
     //...
      dep.notify()
    }

首先 watcher 和dep不了解各位老铁看资料吧,
通俗的讲: watcher1 用到了message属性,那么在触发message get的时候dep将这个watcher1 保存, 然后watcher2 也用到了message 那么就加入watcher2,此时 dep = [watcher1、watcher2],然后在message改变触发set的时候 ,遍历执行每一个watcher.update()…

3.render
上一步 初次渲染 new watcher 有一个回调函数,其中调用_render(就是template->render), 进行render 然后就按照老师说的 生成vnode、patch(elm,vnode)

上面是首次渲染的过程,更新过程同理: 触发set ->watcher.update->触发回调render->patch
总结如下:

//初次渲染
1.initState ->进行双向绑定
2.$mount->将template编译成render函数
3.执行渲染 触发属性get函数,将渲染watcher 收集到dep中
4.调用render 函数 生成vnode
5.patch(elm,vnode)

//更新
1.修改数据 触发属性set
2.然后dep.notify() ->watch.update 派发更新
3.触发render watcher 的render回调
4.生成新的vnode
5.patch(oldVnode,newVnode)
写回答

4回答

双越

2020-03-06

为你点赞!

浅层学习看输入,深层学习看输出。

1
0

23届毕业生

2022-07-18

666送给你老铁

0
0

gyl_lucy

2022-03-29

厉害厉害

0
0

emn

2021-07-20

真棒👍🏻
0
0

2024版 前端框架及项目面试 聚焦Vue3/React/Webpack

面向1-3年前端的框架及项目面试“刚需内容”

4665 学习 · 1644 问题

查看课程