VUE源码:二、vue源码剖析01

目标

  • 环境搭建
  • 掌握源码学习方法
  • vue初始化过程剖析
  • 深入理解数据响应式

资源
vue源码地址:https://github.com/vuejs/vue

知识点

获取vue
项目地址:https://github.com/vuejs/vue
迁出项目: git clone https://github.com/vuejs/vue.git
当前版本号:2.6.11

文件结构

VUE源码:二、vue源码剖析01_第1张图片

源码目录:
VUE源码:二、vue源码剖析01_第2张图片

调试环境搭建

  • 安装依赖: npm i
  • 安装rollup: npm i -g rollup
  • 修改dev脚本,添加sourcemap,package.json
"dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web- full-dev",
  • 运行开发命令: npm run dev
  • 引入前面创建的vue.js,examples/commits/index.html

术语解释:

  • runtime:仅包含运行时,不包含编译器, 体积较小,适合webpack环境,所有模板都是预编译,执行的时候不需要编译器
  • common:cjs 规 范 , 用 于 webpack1
  • esm:ES模块,用于webpack2+打包,规范遵从ES6模块化规范,
  • umd: universal module definition,兼容cjs和amd,用于浏览器,兼容前后端两种模式,可用script直接引用,适合浏览器异步加载模块

入口
两种方式找入口文件:
1、通过堆栈方式:
2、通过对打包工具的了解:
rollup也是打包工具,与webpack很相似,特别流行于js库打包,不涉及素材的东西

dev脚本中-c scripts/config.js 指明配置文件所在
参数TARGET:web-full-dev 指明输出文件配置项,line:123

如何找到源码入口文件:
1、找到package.json的dev配置
在这里插入图片描述
2、找到config.js, 搜索web-full-dev的配置
VUE源码:二、vue源码剖析01_第3张图片
3、找到resolve方法
VUE源码:二、vue源码剖析01_第4张图片
4、可以看一下alias文件内容,方便理解
VUE源码:二、vue源码剖析01_第5张图片
alias里的web属性,就是resolve里面获取的文件名 web

最后可以找到源码的入口文件是: /src/platforms/web/entry-runtime-with-compiler.js
VUE源码:二、vue源码剖析01_第6张图片

初始化流程

整体流程

  • new Vue()
    • _init()
  • $mount()
    • mountComponent()
      • updateComponent()
        • render()
        • update()
      • new Watcher()

初始化文件:
1、src\platforms\web\entry-runtime-with-compiler.js
主要代码:

import Vue from './runtime/index'

// 扩展$mount方法
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
	 // 用户配置选项
	  const options = this.$options
	  // resolve template/el and convert to render function
	  // 获取渲染函数
	  // el < template < render   优先级
	  if (!options.render) {
	  	if (template) {
			...
		} else if (el) {
      		template = getOuterHTML(el)
   		 }
   		 // 获取模板之后,编译它
	    if (template) {
			// 编译:获取渲染函数
	      const { render, staticRenderFns } = compileToFunctions(template, {
	        outputSourceRange: process.env.NODE_ENV !== 'production',
	        shouldDecodeNewlines,
	        shouldDecodeNewlinesForHref,
	        delimiters: options.delimiters,
	        comments: options.comments
	      }, this)
		}
		// 执行默认挂载功能
		return mount.call(this, el, hydrating)
	  }

源着上一个文件的vue导入,找到这个文件:
2、src\platforms\web\runtime\index.js

import Vue from 'core/index'
// install platform patch function
// 1.声明一个补丁函数
Vue.prototype.__patch__ = inBrowser ? patch : noop

// public mount method
// 2.声明$mount方法:
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  // 挂载执行
  return mountComponent(this, el, hydrating)
}

// devtools global hook
/* istanbul ignore next */
//控制台提示使用vue-devtools  和  vue版本提示
if (inBrowser) {
	if(!config.devtools){
		console[console.info ? 'info' : 'log'](
          'Download the Vue Devtools extension for a better development experience:\n' +
          'https://github.com/vuejs/vue-devtools'
        )
	}
	console[console.info ? 'info' : 'log'](
        `You are running Vue in development mode.\n` +
        `Make sure to turn on production mode when deploying for production.\n` +
        `See more tips at https://vuejs.org/guide/deployment.html`
      )
}

关于vue-tools 和 vue版本提示表现在浏览器的console,如图
VUE源码:二、vue源码剖析01_第7张图片
源着上一个文件导入的vue路径,找到如下文件
3、\src\core\index.js

import Vue from './instance/index'

// 初始化全局api
// 包括defineReactive、set、delete、nextTick、Use、Mixin、Extend、AssetRegisters等
initGlobalAPI(Vue)

// 判断是否是服务端渲染
Object.defineProperty(Vue.prototype, '$isServer', {
  get: isServerRendering
})
Object.defineProperty(Vue.prototype, '$ssrContext', {
  get () {
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext
  }
})
// expose FunctionalRenderContext for ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
  value: FunctionalRenderContext
})

源着上面文件导入的vue文件路径,找到下面的文件:
4、src\core\instance\index.js

// 真正的VUE构造函数
function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  // 初始化
  this._init(options)
}

// 实例方法的初始化
initMixin(Vue) // 混入_init()
stateMixin(Vue) // $set/$delete/$watch
eventsMixin(Vue) // $emit/$on/$off/$once
lifecycleMixin(Vue) // $_update/$forceUpdate
renderMixin(Vue)

你可能感兴趣的:(vue源码)