vue源码

  • vue静态成员(Vue.set() Vue.use() Vue.extend().... )和实例成员(vm.$on vn.$emit...)初始化过程

  • vue首次渲染的过程
  • vue响应式机制
vue核心文件结构(src下)
  • compiler (把template模板转换成render函数,render函数创建虚拟DOM)
  • core
    1 components 定义了keep-alive组件
    2 global-api 定义了vue静态方法 Vue.extend Vue.use ....
    3 instance vue实例创建
    4 observer 实现响应式
    5 util 公共方法
    6 vdom 虚拟DOM 重写了snabbdom
  • platforms 平台相关代码 1 web 2 weex
  • server 服务端渲染相关
  • sfc 把vue单文件组件转换成js对象
  • shared 功能代码
    静态类型检查采用flow
    打包工具采用Rollup ,比webpack轻,webpack把所有文件当做模块 ,rollup只处理js文件 更适合vue这样的js库开发,Rollup不会生成冗余代码

调试设置

  • cnpm i 安装依赖
  • 设置source-map "dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev" 开启代码地图后在打断点会生成src源码目录,可以打开对应源码文件
  • npm run dev打包

打包后的不同版本vue

  • npm run build 编译打包不同版本的vue
    完整版带编译器,可以把template转换为render函数,但体积大,运行时版本不带编译器(runtime) vue-cli运行使用的是vue.runtime.esm.js 运行时es版本,有tree-shaking功能
  • vue-cli 可以使用 vue inspect > output.js可以输出webpack配置文件,但不能直接使用,可以查看配置参数,可以看到vue-cli导入的vue是vue.runtime.esm.js 版本

vue模板编译过程

  • 模板编译主要是将模板转换为为render渲染函数的过程
作用
  • vue2.0使用vnode描述视图和各种交互,用户自己编写vnode比较复杂
  • 用户只需编写类型html代码模板,通过编译器将模板转换为返回vnode的render函数
  • .vue文件会在webpack构建过程中被转换为render函数(通过vue-loader)
编译模板文件位置 src/platforms/web/entry-runtime-with-compile.js
  • 首先判断用户传入的render是否存在
  • 没有render继续判断是否存在template,有的话template为模板内容
  • 没有判断是否选项中是否有el属性,有的话把el的outerHTMl作为模板,调用comlieToFunctions把template转化为render函数

模板编译的例子

  • 编译前模板
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>compile</title>
</head>
<body>
<!--模板内容-->
  <div id="app">
    <h1>Vue<span>模板编译过程</span></h1>
    <p>{{ msg }}</p>
    <comp @myclick="handler"></comp>
  </div>
  <script src="../../dist/vue.js"></script>
  <script>
    Vue.component('comp', {
      template: '<div>I am a comp</div>'
    })
    const vm = new Vue({
      el: '#app',
      data: {
        msg: 'Hello compiler'
      },
      methods: {
        handler () {
          console.log('test')
        }
      }
    })
    console.log(vm.$options.render)
   
  </script>
</body>
</html>
  • 编译后的render函数内容
  function anonymous() {
      with (this) {
        return _c('div', {
          attrs: {
            "id": "app"
          }
        },
        [ _m(0),
          _v(" "),
          _c('p',
          [_v(_s(msg))]),
          _v(" "),
          _c('comp', {
            on: {
              "myclick": handler
            }
          })], 1)
      }
    }
  • _c('p',[_v(_s(msg))]), 创建p标签对应vnode,第二个参数为数组包含的文本,用户手写的render函数第二个参数可以直接是一个文本内容,会通过normizeChildren转化为这个数组形式
  • with (this)可以让代码块中使用this的地方省略this
  • 其中 _v _c _m都是this vue实例方法
  • _c 是 createElement() 方法,定义的位置 src/core/instance/render.js 中
vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
  • _m _v _s,在 src/core/instance/render-helps/index.js 中
  • _m 设置静态内容
  • _v创建包含文本的vnode
  • _s参数转化为字符串
export function installRenderHelpers (target: any) {
  target._s = toString
  target._m = renderStatic  
  target._v = createTextVNode

}

模板编译函数

  • compileToFunctions: 把template编译为render函数 把生成的render记录到options属性中 src/platforms/web/entry-runtime-with-compile.js
  • compileToFunctions : 在 src/platforms/web/compile/index中导出 createCompiler函数生成 参数baseOptions
  • createCompiler src/complie/index.js定义
QQ截图20201006150241.png

抽象语法树

  • 使用对象形式描述树形代码结构,树形结构的html字符串
  • 使用ast好处:
    1. 模板字符串转换为ast后,可以通过ast对模板进行优化
    2. 标记模板中的静态内容,在patch的时候跳过静态内容
    3. 在patch过程中静态内容不需要对比和重新渲染

组件化 一个用于预定义选项的vue实例

vue组件化

vue.component注册组件内部实现
  • src/core/global-api/index.js initAssetRegisters定义
  • 第二个参数为对象,会调用vue.extend,把组件配置转换为组件的构造函数
  • 第二个参数为函数会把参数记录到options选项的components中
vue.extend
  • src/core/global-api/extend.js
  • 接受参数 组件的选项对象 通过传入的选项创建组件的构造函数,继承与vue的构造函数
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349