下载去github上下载Vuenpm install npm run dev运行起来rollup + flowvue使用使用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/indeximport Vue from ‘core/index’Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean): Component { el = el && inBrowser ? query(el) : undefined return mountComponent(this, el, hydrating)}export default Vue在vue原型上添加了mount方法处理了devtools,没有安装提醒安装devtools给了这句提示dev环境提示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)打开initexport function initMixin (Vue) { Vue.prototype._init = function (options?: Object) { const vm = this // a uid vm._uid = uid++ let startTag, endTag /* istanbul ignore if / if (process.env.NODE_ENV !== ‘production’ && config.performance && mark) { startTag = vue-perf-start:${vm._uid}
endTag = vue-perf-end:${vm._uid}
mark(startTag) } // a flag to avoid this being observed vm._isVue = true // 处理传入的options // merge options if (options && options._isComponent) { // optimize internal component instantiation // since dynamic options merging is pretty slow, and none of the // internal component options needs special treatment. initInternalComponent(vm, options) } else { // 传入的options,默认的options一起合并挂载到vm.$options上 vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options || {}, vm ) } / istanbul ignore else / if (process.env.NODE_ENV !== ‘production’) { // 代理 initProxy(vm) } else { vm._renderProxy = vm } // 生命周期 initLifecycle(vm) // emit on 事件 initEvents(vm) // 处理render vdom initRender(vm) callHook(vm, ‘beforeCreate’) // 处理Injections initInjections(vm) // resolve injections before data/props // 双向数据绑定,监听订阅 initState(vm) initProvide(vm) // resolve provide after data/props callHook(vm, ‘created’) / istanbul ignore if / if (process.env.NODE_ENV !== ‘production’ && config.performance && mark) { vm._name = formatComponentName(vm, false) mark(endTag) measure(vue ${vm._name} init
, startTag, endTag) } // 渲染到dom if (vm.$options.el) { vm.$mount(vm.$options.el) } }}lifecycle打开 lifecycleexport 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 的时候,是执行相应周期,开发者在周期函数里所写的EventsinitEvents实现了 emit on 等方法,请参考监听者订阅者模式,这里不详解renderrenderMixin函数添加了 $nextTick _render 原型对象$nextTick会在dom跟新后立即调用nextTick(fn, this)是一个自执行函数_render返回的是node的js数据,还不是dom做了VdominitRender函数给vm添加了_c和 $createElement用来渲染的方法stateif (!(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-alivecore/util 封装了通用方法core/vdom vdom算法以上整体架构分析完毕附张图