实例讲解vue源码架构
下载
去github上下载Vue https://github.com/vuejs/vue
npm install npm run dev
运行起来
rollup + flow
vue使用使用rollup打包,flow规范数据类型
rollup可以先用webpack套用,读起来差不多,时间有限,毕竟只有5分钟,这个就不用去看rollup文档了
入口
打开package.json
我们看scripts配置
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev", "dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs-dev",
找到scripts/config.js
打开
根据配置TARGET的不同会选择不同的config
同时在这里配置了process.env.NODE_ENV 环境
TARGET有CommonJS,ES Modules,UMD关于js引入类型的
还有weex,ssr
'web-runtime-cjs-dev': { entry: resolve('web/entry-runtime.js'), dest: resolve('dist/vue.runtime.common.dev.js'), format: 'cjs', env: 'development', banner }
在alias.js下设置了别名路径
我们先介绍src/platforms
里面有web和weex 分别的web和weex入口
在web文件下是CommonJS,ES Modules,UMD关于js引入类型,server的打包入口
打开web/entry-runtime.js
引入
import Vue from './runtime/index' export default Vue
打开./runtime/index
import Vue from 'core/index' Vue.prototype.$mount = function ( el"htmlcode">You are running Vue in development mode. Make sure to turn on production mode when deploying for production. See more tips at https://vuejs.org/guide/deployment.htmlplatforms目录夹讲解完毕
core目录
打开core/instance/index
映入眼前的是
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) stateMixin(Vue) eventsMixin(Vue) lifecycleMixin(Vue) renderMixin(Vue) export default Vue先执行的是initMixin(Vue)
打开init
export function initMixin (Vue) { Vue.prototype._init = function (options"htmlcode">export function callHook (vm: Component, hook: string) { // disable dep collection when invoking lifecycle hooks pushTarget() //执行对象的周期函数,周期函数最后被处理成数组 const handlers = vm.$options[hook] const info = `${hook} hook` if (handlers) { for (let i = 0, j = handlers.length; i < j; i++) { invokeWithErrorHandling(handlers[i], vm, null, vm, info) } } if (vm._hasHookEvent) { vm.$emit('hook:' + hook) } popTarget()callHook 的时候,是执行相应周期,开发者在周期函数里所写的
Events
initEvents实现了 emit on 等方法,请参考监听者订阅者模式,这里不详解
render
renderMixin函数
添加了 $nextTick _render 原型对象$nextTick会在dom跟新后立即调用
nextTick(fn, this)是一个自执行函数
_render返回的是node的js数据,还不是dom
做了Vdom
initRender函数
给vm添加了_c和 $createElement用来渲染的方法state
if (!(key in vm)) { proxy(vm, `_props`, key) }给vue属性做代理,访问this.a可以得到this.data.a 的值
export function initState (vm: Component) { vm._watchers = [] const opts = vm.$options if (opts.props) initProps(vm, opts.props) if (opts.methods) initMethods(vm, opts.methods) if (opts.data) { initData(vm) } else { observe(vm._data = {}, true /* asRootData */) } if (opts.computed) initComputed(vm, opts.computed) if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch) } }给数据做监听
stateMixin函数
添加原型对象
Vue.prototype.$set = set Vue.prototype.$delete = del其他
src/compiler 做了编译处理
core/componetd 做了keep-alive
core/util 封装了通用方法
core/vdom vdom算法
以上整体架构分析完毕
下一篇:详解Node.js amqplib 连接 Rabbit MQ最佳实践
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?