Vue(一)

2020-12-03  本文已影响0人  _1633_

new Vue

new Vue

    1. 当我们 new Vue 的时候,会执行 _init 方法。

 _init 

    2.  _init 方法再原型上(中间省略 n 多代码)

_init方法执行 $mount

    3. $mount 方法挂载 vm,$mount 在很多文件都有定义,因为 $mount 跟 所在的平台有关系,这里我们看的是 src/platform/web/entry-runtimewith-compiler.js 

    注意: 如果没有定义 render 方法,则会把 el 或者 template 字符串转换成 render 方法,,所有 Vue 的组件的渲染最终都需要 render 方法。

$mount

        4. $mount 

            还是执行 $mount,接受上面传递的两个参数,第一个参数 el,它表示挂载的元素,可以是字符串,也可以是 DOM 对象,第二个参数浏览器上忽略。

$mount 

    5. moutComponent

        在 moutComponent 中 我们调用了 updateComponent

        执行  vm._update(vm._render(), hydrating)

moutComponent

    6. _render

    _render 方法执行了 render 方法并传入 参数 vm.$createElement, render = vm.$options.render

_render

    在官网的例子中, 使用 render 代替模板语法,它的第一个参数 createElement 就是我们的 vm.$createElement

render函数

    render 函数又执行了 createElement

createElement

vm._render 通过执⾏ createElement ⽅法并返回的是 vnode


    7. createElement 

        返回 vnode

        _createElement ⽅法有 5 个参数, 就是我们经常手写的 render 函数,context 表⽰ VNode 的上下文环境,它是 Component 类型; tag 标签,它可以是⼀个字符串,也可以是⼀个 Component ; data 是 VNode 的数 据; children 是 VNode 的⼦节点,它是任意类型的; normalizationType  是子节点规范的类型,类型不同规范的方法也就不⼀样,它主要是参 考 render 函数是编译⽣成的还是⽤户⼿写的。

createElement

    8. 再回到 第5步的 _update

          vm._update(vm._render(), hydrating), _render() 返回了 vnode,接着 执行 _update,_update 是实例的⼀个私有⽅法,它被调用的时机有 2 个,⼀个是首次渲染,⼀个是数据更 新的时候。 _update 的核新就是调用  vm.__patch__ 方法。

__patch__

    浏览器环境下     Vue.prototype.__patch__ = inBrowser ? patch : noop

    var patch = createPatchFunction({

          nodeOps: nodeOps,

          modules: modules

    });

    patch 就是 createPatchFunction 的返回值, 它返回了另外一个 patch 函数,,这个方法就 赋值给了 vm._update 函数⾥调⽤的 vm.__patch__ 。

     patch  方法本⾝,它接收 4个参数, oldVnode 表示旧的 VNode 节点,它也可以不存在或者是 ⼀个 DOM 对象; vnode 表示执行  _render 后返回的 VNode 的节点; hydrating  表示是否是服务端渲染; removeOnly 是给 transition-group 用的

createPatchFunction

        在函数中调用 createElm, createElm 的作用是通过虚拟节点创建真实的 DOM 并插⼊到它的父节点中。如果 vnode 节点如果不包含 tag ,则它有可能是⼀个注释或者纯⽂本节 点,可以直接插⼊到⽗元素中。就是最后一个 else 逻辑:

        vnode.elm = nodeOps.createTextNode(vnode.text);

        insert(parentElm, vnode.elm, refElm);

createElm

        createChildren  方法去创建子元素

createChildren

        insert ⽅法把 DOM 插⼊到⽗节点中,因为是递归调用,子元素会优先调用insert , 所以整个 vnode 树节点的插⼊顺序是先⼦后父。

insert

    nodeOps 就是一些原生的 DOM 操作,比如 insertBefore, appendChild, 在 src/platforms/web/runtime/node-ops.js 中。

    首次渲染我们调用了 createElm 方法,这⾥传入的 parentElm 是 oldVnode.elm 的父元素, 比如 一般我们都是使用 id 为 #app div 的父元素,也就是 Body;实际上整个过 程就是递归创建了⼀个完整的 DOM 树并插入到 Body 上。

大概流程
上一篇下一篇

猜你喜欢

热点阅读