zoukankan      html  css  js  c++  java
  • Vue源码编译过程

    Vue源码编译过程

    一、挂载
    初始化$mounted会挂载组件,不存在 render 函数时需要编译(compile);

    二、compile
    1.compile 分为 parse,optimize 和 generate,最终得到 render 函数;

    2.parse 调用 parseHtml 方法,方法核心是利用正则解析 template 的指令,class 和 stype,得到 AST;

    3.optimize 作用标记 static 静态节点,后面 patch,diff会跳过静态节点;

    4.generate 是将 AST 转化为 render 函数表达式,执行 vm._render 方法将 render 表达式转化为VNode,得到 render 和 staticRenderFns 字符串;

    5.vm._render 方法调用了 VNode 创建的方法createElement
    // render函数表达式
    (function() {
    with(this){
    return _c('div',{ //创建一个 div 元素
    attrs:{"id":"app"} //div 添加属性 id
    },[
    _m(0), //静态节点 header,此处对应 staticRenderFns 数组索引为 0 的 render function
    _v(" "), //空的文本节点
    (message) //判断 message 是否存在
    //如果存在,创建 p 元素,元素里面有文本,值为 toString(message)
    ?_c('p',[_v(" "+_s(message)+" ")])
    //如果不存在,创建 p 元素,元素里面有文本,值为 No message.
    :_c('p',[_v(" No message. ")])
    ]
    )
    }
    })

    三、依赖收集与监听
    这部分是数据响应式系统
    1.调用 observer(),作用是遍历对象属性进行双向绑定;

    2.在 observer 过程中会注册Object.defineProperty的 get 方法进行依赖收集,依赖收集是将Watcher 对象的实例放入 Dep 中;

    3.Object.defineProperty的 set 会调用Dep 对象的 notify 方法通知它内部所有的 Watcher 对象调用对应的 update()进行视图更新;

    4.本质是发布者订阅模式的应用

    四、diff 和 patch
    diff 算法对比差异和调用 update更新视图:

    1.patch 的 differ 是将同层的树节点进行比较,通过唯一的 key 进行区分,时间复杂度只有 O(n);

    2.上面将到 set 被触发会调用 watcher 的 update()修改视图;

    3.update方法里面调用patch()得到同级的VNode 变化;

    4.update 方法里面调用createElm通过虚拟节点创建真实的 DOM 并插入到它的父节点中;

    5.createElm实质是遍历虚拟 dom,逆向解析成真实 dom;

  • 相关阅读:
    环形缓冲区: ringbuf.c
    Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析
    list.h在用户态下的应用
    如何优雅的拔盘?
    谨慎调整内核参数:vm.min_free_kbytes
    Linux内核tracepoints
    网卡多队列
    How to use pthread_create && mutex?
    美国电子工程师最值得打工的50个东家
    关于零点和极点的讨论
  • 原文地址:https://www.cnblogs.com/guwufeiyang/p/13279445.html
Copyright © 2011-2022 走看看