• vue04-源码学习方法


    项目地址:https://github.com/vuejs/vue

    迁出项目:git clone https://github.com/vuejs/vue.git

     

    目录机构:

    dist:最终输出目标,运行在不同的运行时里

    examples:官方准备的案例

    flows:(类型声明)vue2用flows语言编写,类似于ts,强类型编译语言,有一些语言的类型声明文件,明确告诉你都实现了那些方法及方法的签名是怎样的

    packages:有一些独立的包如vue-server-render:vue服务端渲染器;作为一些独立的包存在,和vue的核心功能有区分

    scripts:打包的脚本,用什么方法打包,打包的配置,入口文件的查找跟此包息息相关

    src:核心代码存放:compiler(编译器)、core(vue核心代码)、plateform(平台持有代码web weex)

    server:服务端相关东西

    sfc:单文件解析器

    shared:少量共享代码

    types:ts类型文件(专门为ts编写了一套文件)

     

    调试环境搭建:

    安装依赖:npm i

    安装rollup:npm i -g rollup (打包工具,与webpack的区别在于他用于纯js库的编写)

    修改dev脚本,添加sourcemap -> package.json

    "dev":"rollup -w -c scripts/config.js --sourcemap --environment TARGE:web-full-dev"

    运行:npm run dev

    //运行完可看见文件的入口:entry-runtime-with-compiler.js   

    验证是否成功:dist下的vue.js目录颜色变了;多了vue.js.map文件

    写一个html文件,将dist/vue.js引进去就可以了,打开文件就可以了调试了,F12-sources-有src目录(所有源码的结构,刚才的步骤代表成功)-文件-打断点-调试

     

    dist文件中,输出版本的术语:

    common关键字:nodejs模块,叫cjs,运行在旧版打包器webpack1,broswerify

    esm:es模块化规范,常用语webpack2+  不带编译器

    umd(无后缀):兼容cjs和amd规范,常用语浏览器,但也可用于服务端

    runtime:说明输出的库仅有核心运行时代码,没有编译器

     

    寻找入口文件的方法:

    package.json文件中,scripts下的dev的配置中-c后面的文件就是配置文件(scripts/config.js),最终的输出目标是(TARGET:web-full-dev),打开配置文件,寻找web-full-dev关键字,就找到了入口文件

     

     如何找到web/entry-runtime-with-compiler.js,核心在resolve里,当前文件找到resolve方法

     

    他是传入一个地址,然后将地址稍微做一下处理,转为一个绝对地址出去,(通过/分开两部分,web和文件名,web会通过aliases里查找具体路径,)我们打开./alias文件,找到web对应的源码路,再加上后面的后缀名找到具体文件(src/plateforms/web/entry-runtime-with-compiler.js)

    vue的初始化流程:

    根据上一节vue03的流程图,vue的整体流程是两条线,第一条是初始化这条线;第二条是更新的这条线;我们研究第一条初始化流程

    整体流程:(只大致说下实现了什么,不上源码图了,大家根据源码对照着看)

    1.入口:src/platforms/web/entry-runtime-with-compiler.js

       入口文件主要做的事情:首先获取原始$mount方法,并扩展;然后处理跟render/template/el相关的选项(优先级:render>template>el) ;然后开始编译,将用户编写的模板转换为渲染函数(compileToFunctions实现);最后执行挂载(虚拟DOM转化为真实     DOM)

    2.Vue的构造函数:图中初始化的点是Vue构造函数,入口文件中Vue的引入在runtime/index,我们打开这个文件

      

      src/platforms/web/runtime/index:首先定义补丁函数patch(patch()做更新,将虚拟DOM变为真实DOM),定义挂载函数$mount(对函数mountComponent的调用,挂载逻辑需研究此函数,主要实习渲染<获取vdom>、更新<将vdom转换为dom>)

      此文件未找到Vue的构造函数,此文件中找到Vue的引入在core/index,我们打开这个文件

      

       src/core/index:初始化全局API(initGlobalAPI(Vue));定义一些属性,看起来和服务端渲染有关直接跳过去,主要实现全局API,点进去看一下这个方法

        initGlobalAPI(Vue):主要实现声明全局API,(我们随便打开里面的inituse方法看一下,我们就知道为什么Vue.use()方法会调用插件的install方法了);

      此文件中也没有Vue的初始化,根据引入的地址我们找instance/index

      

     src/core/instance/index.js:终于找到了----初始化中只执行了init方法,我们回想那张图,初始化中执行了init方法

      

       init方法是哪来的,我们看下面有或多Mixin方法,典型的混入模式,对Vue进行扩展,我们看一下怎么进行混入的,initMixin方法来自./init文件,我们点进去看一下,只给了原型一个init的方法,实现了扩展,如果研究初始化方法,init就是核心方法

      

       看一下里面的核心代码,进行一些初始化,初始化顺序:生命周期,事件监听,渲染,beforeCreate,注入,组件状态(数据,属性,methods,watch),数据响应化,提供数据,created;然后如果存在el宿主,则执行挂载---(进入入口文件);

       

            initLifecycle():初始化声明$parent,$root,$children,$refs等

      initEvent():事件监听的开始,事件的起始点

      initRender():渲染相关的东西($slots,$scopedSlots,$createElement,_c) 

    数据响应式:

      mvvm框架最大特点数据响应式

      ·对象响应式:Object.defineProperty

      ·数组响应式:  

       src/core/instance/state.js----initState方法

       数据响应化定义

    异步更新队列:

    •  vue更新dom是异步的:修改了一个data,dom不会立刻更新(updata()------》queueWatcher(this)-----》nextTick())
    • 是批量的:对同一个数据的连续同一个操作,他不会执行多次
  • 相关阅读:
    HashMap循环遍历方式及其性能对比
    打印沙漏1
    第七周实验报告与总结5
    第四周总结与试验
    第六周实验报告4
    数据库学习之一
    Euler猜想
    pip安装模块
    python 自带的ide 不能保存文件
    javaWeb高级编程(1)
  • 原文地址:https://www.cnblogs.com/znLam/p/12920724.html
Copyright © 2020-2023  润新知