web与网络基础(二)|8月更文挑战

127 阅读2分钟

微信公众号:  [大前端驿站]
关注大前端驿站。问题或建议,欢迎公众号留言。

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

Vue是当今最火的前端框架之一,是一套优秀的前端渐进式框架,它的简单易用性的特点也是众多前端工程师选择的原因。但是想要在众多Vue工程师中脱颖而出,其原理是必须要掌握的,接下来我们一起通过源码分析的角度来学习vue2的一些原理知识。

调试环境搭建

获取vue

掌握学习的方法很重要,我们先将vue2的源代码clone下来,然后看看部分重要的源码目录。

项目地址:https://github.com/vuejs/vue
git 执行:git clone https://github.com/vuejs/vue.git
当前版本:"2.6.14" cloneVue2.png 安装依赖

npm i

安装到phantom.js时如果特别慢,这时可以提前终止

安装rollup

npm i rollup -g

修改package.json中的dev脚本,添加sourcemap

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

执行开发命令构建vue.js

npm run dev

注意目录不要有中文,不然构建可能会出现报错 构建完成后dist目录中会生成重新构建好的sourcemap的vue.js

修改examples/commit/index.html

<!-- <script src="../../dist/vue.min.js"></script> -->
    <script src="../../dist/vue.js"></script>

打开index.html,我们可以看到sourcemap的调试便利之处

vue.min.png vue.js可以断点调试代码

vuejs.png


术语解释:

  • runtime: 仅包含运行时,不包含编辑器
  • common: cjs规范,用于webpack1
  • esm: ES模块,用于webpack2
  • umd: 兼容cjs和amd,用于浏览器

目录结构

vue2源码目录,我们重点关注源代码目录

vueMenu.png 源代码子目录

core.png

入口

我们执行执行package.json中的dev脚本,分析脚本知道从scripts/config.js中找到目标环境为web-full-dev处123行

// 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
},

此处我们可以看到入口文件是web/entry-runtime-with-compiler.js,但是并没有找到web目录,这是我们可以想到大概是设置了别名,然后确实在scripts/alias.js中找到了

 web: resolve('src/platforms/web'),

然后我们定位到了入口文件src/platforms/web/entry-runtime-with-compiler.js

整体流程

我们从入口文件一步步推导它引入了哪些文件,看看这些文件都做了哪些工作

platforms/web/entry-runtime-with-compiler.js

主要作用:扩展默认的$mount方法,处理template或者el选项

import Vue from './runtime/index'
...
const mount = Vue.prototype.$mount
...

platforms/web/runtime/index

安装web平台特有指令和组件 定义__patch__:补丁函数,执行patching算法进行更新 定义$mount:挂载vue实例到指定宿主元素(获得dom并替换宿主元素)

core/index.js

初始化全局api

Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick 
initUse(Vue) // 实现Vue.use函数 
initMixin(Vue) // 实现Vue.mixin函数 
initExtend(Vue) // 实现Vue.extend函数 
initAssetRegisters(Vue) // 注册实现Vue.component/directive/filter

core/instance/index.js

定义Vue构造函数 定义Vue实例api

function Vue (options) { 
  // 构造函数仅执行了_init 
  this._init(options) 
}
initMixin(Vue) // 实现init函数
stateMixin(Vue) // 状态相关api $data,$props,$set,$delete,$watch 
eventsMixin(Vue) // 事件相关api $on,$once,$off,$emit 
lifecycleMixin(Vue)  // 生命周期api _update,$forceUpdate,$destroy 
renderMixin(Vue)// 渲染api _render,$nextTick

core/instance/init.js

创建组件实例,初始化其数据、属性、事件等

initLifecycle(vm) // $parent,$root,$children,$refs
initEvents(vm) // 处理父组件传递的事件和回调
initRender(vm) // $slots,$scopedSlots,_c,$createElement
callHook(vm, 'beforeCreate')
initInjections(vm) // 获取注入数据
initState(vm) // 初始化props,methods,data,computed,watch
initProvide(vm) // 提供数据注入
callHook(vm, 'created')

$mount: mountComponent

执行挂载,获取vdom并转换为dom

new Watcher()

创建组件渲染watcher

updateComponent()

执行初始化或更新

update()

初始化或更新,将传入vdom转换为dom,初始化时执行的是dom创建操作

render(): src\core\instance\render.js

渲染组件,获取vdom


Vue初始化的整体流程

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

关注下方【大前端驿站】
让我们一起学,一起进步

【分享、点赞、在看】三连吧,让更多的人加入我们~~