vue源码分析

一、Vue 源码解析 - 响应式原理

1.1 准备工作

  • 源码目录结构
src
├─compiler 编译相关
├─core Vue 核心库
├─platforms 平台相关代码
├─server SSR,服务端渲染
├─sfc .vue 文件编译为 js 对象
└─shared 公共的代码
  • vue采用flow静态类型检查器

  • 调试, vue 采用rollup打包工具,设置 sourcemap,package.json 文件中的 dev 脚本中添加参数 --sourcemap

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

1.2 Vue的不同构建版本

  • npm run build 重新打包所有文件
UMDCommonJSES Module
Fullvue.jsvue.common.jsvue.esm.js
Runtim-onlyvue.runtime.jsvue.runtime.common.jsvue.runtime.esm.js
Full(production)vue.min.js-
Runtime-only(production)vue.runtime.min.js-

术语

  • 完整版:同时包含编译器和运行时的版本。

  • 编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码。

  • 运行时:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的代码。基本上就是除去编译器的其它一切。

  • UMD:UMD 版本可以通过 <script> 标签直接用在浏览器中。jsDelivr CDN 的 https://cdn.jsdelivr.net/npm/vue 默认文件就是运行时 + 编译器的 UMD 版本 (vue.js)。

  • CommonJS:CommonJS 版本用来配合老的打包工具比如 Browserifywebpack 1。这些打包工具的默认文件 (pkg.main) 是只包含运行时的 CommonJS 版本 (vue.runtime.common.js)。

  • ES Module:从 2.6 开始 Vue 会提供两个 ES Modules (ESM) 构建文件:

    • 为打包工具提供的 ESM:为诸如 webpack 2Rollup 提供的现代打包工具。ESM 格式被设计为可以被静态分析,所以打包工具可以利用这一点来进行“tree-shaking”并将用不到的代码排除出最终的包。为这些打包工具提供的默认文件 (pkg.module) 是只有运行时的 ES Module 构建 (vue.runtime.esm.js)。

    • 为浏览器提供的 ESM (2.6+):用于在现代浏览器中通过 <script type="module"> 直接导入。****

寻找入口文件

  • 查看 dist/vue.js 的构建过程

  • 其实可以执行yarn dev文件 查看打包结果也可以直接查看入口文件

在这里插入图片描述

执行构建

npm run dev
# "dev": "rollup -w -c scripts/config.js --sourcemap --environment
TARGET:web-full-dev"
# --environment TARGET:web-full-dev 设置环境变量 TARGET
  • script/config.js 的执行过程

    • 作用:生成 rollup 构建的配置文件

    • 使用环境变量 TARGET = web-full-dev

// 判断环境变量是否有 TARGET
// 如果有的话 使用 genConfig() 生成 rollup 配置文件
if (process.env.TARGET) {
 module.exports = genConfig(process.env.TARGET)
} else {
 // 否则获取全部配置
 exports.getBuild = genConfig
 exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
}
  • genConfig(name)

    • 根据环境变量 TARGET 获取配置信息

    • builds[name] 获取生成配置的信息

// Runtime+compiler development build (Browser)
 'web-full-dev': {
  entry: resolve('web/entry-runtime-with-compiler.js'),
  dest: resolve('dist/vue.js'),
  format: 'umd',
  env: 'development',
  alias: { he: './entity-decoder' },
  banner
},
  • resolve()

    • 获取入口和出口文件的绝对路径
const aliases = require('./alias')
const resolve = p => {
 // 根据路径中的前半部分去alias中找别名
 const base = p.split('/')[0]
 if (aliases[base]) {
  return path.resolve(aliases[base], p.slice(base.length + 1))
} else {
  return path.resolve(__dirname, '../', p)
}
}

通过调用栈的方式查看$mount在哪里调用

在这里插入图片描述

问题:以下代码页面渲染的结果是

    new Vue({
      el: '#app',
      template: '<h1>我是template</h1>',
      render (h) {
        return h('h1', '我是reder渲染的')
      },
    })

答案:在这里插入图片描述

分析:可以通过源码中的 if(!options.render)来判断,这句话的作用是如果render不存在,就会将template转换成render函数

在这里插入图片描述

Vue阅读源码需要注意的事项

vscode会出现红色波浪线报错 和 源码没有高调的情况

在这里插入图片描述

需要做的就是在vue项目的根目录建立.vscode/settings.json

{
  // 设置不检查js的语法问题,防止flow报错
  "javascript.validate.enable": false
}

同时为vscode安装 Babel javascript 插件可以解决高亮的问题, 有一个缺陷就是不能跳转到源码的位置

在这里插入图片描述

1.2 三种类型的Watcher对象

Watcher主要分为三种:computed watcher、用户自定义watcher(侦听器)、渲染watcher

  • 创建顺序是 computed watcher -> 用户自定义watcher -> 渲染watcher

1.3 vue中采用key的好处(diff算法)

1.4 Vue模板编译过程

把html模板转换成render函数工具

Vue3.0 Template Explorer

Vue2.x Template Explorer

_c 函数定义路径:src\core\instance\render.js

_m, _v, _s函数的定义路径:src\core\instance\render-helpers\index.js

AST抽象语法树

  • 抽象语法树简称AST

  • 使用对象的形式描述树形的代码结构

  • 此处的抽象语法树是用来描述树形结构的HTML字符串

astexplorer 抽象语法树查看

Vue.js 源码剖析-响应式原理、虚拟 DOM、模板编译和组件化

一、简答题

1、请简述 Vue 首次渲染的过程。

在这里插入图片描述

2、请简述 Vue 响应式原理。

在这里插入图片描述

3、请简述虚拟 DOM 中 Key 的作用和好处。

首先需要说明diff算法的原理

  • 老开始节点和新开始节点对比

  • 老结束节点和新结束节点对比

  • 老开始节点和新结束节点对比

  • 老结束节点和新开始节点对比

  • 上述情况都不满足才会老节点找新节点存在的索引

不设置或者设置key为index索引值,当往数组中splice插入一个元素时,会在updateChildren方法中,里面的sameVnode方法会判断为同一个vnode,不断比较老开始节点和新开始节点,索引向后移动,子节点会多次操作dom消耗性能。

function sameVnode (a, b) {
  return (
    a.key === b.key && (
      (
        a.tag === b.tag &&
        a.isComment === b.isComment &&
        isDef(a.data) === isDef(b.data) &&
        sameInputType(a, b)
      ) || (
        isTrue(a.isAsyncPlaceholder) &&
        a.asyncFactory === b.asyncFactory &&
        isUndef(b.asyncFactory.error)
      )
    )
  )
}
4、请简述 Vue 中模板编译的过程。在这里插入图片描述
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值