源码入口分析备注:仅用于学习源码过程中的总结。很多不详和错误的地方,后期会进行优化。Vue提供了不同的平台和版本。浏览器环境版本包括:Runtimeonly版本和Runtime+compiler版本。Runtime+compilerversion:newVue({template:'
{{hi}}}
'}),需要将模板中的字符串编译成render函数,需要用到编译器,具体在scripts\config.jsconstbuilds={'web-runtime-cjs-dev':{entry:resolve('web/entry-runtime.js'),dest:resolve('dist/vue.runtime.common.dev.js'),格式:'cjs',env:'development',banner},...'web-full-cjs-dev':{entry:resolve('web/entry-runtime-with-compiler.js'),dest:resolve('dist/vue.common.dev.js'),格式:'cjs',env:'development',别名:{he:'./entity-decoder'},banner},...}本文分析runtime+complier版本,entry属性值为vue源码入口,然后查看web/entry-runtime-with-compiler.jsimportVuefrom'./runtime/index'...//define在runtime/index.jsmount方法缓存constmount=Vue.prototype.$mount//重写$mount//runtime+compilerversionmountVue.prototype.$mount=function(el?:string|Element,hydrating?:boolean//relatedtoserverrendering):Component{el=el&&query(el)/*istanbulignoreif*///当el不可用时body和htmlif(el===document.body||el===document.documentElement){process.env.NODE_ENV!=='production'&&warn(`不要将Vue挂载到或-而是挂载到普通元素。`)returnthis}constoptions=this.$options//resolvetemplate/elandconverttorenderfunction//如果没有定义render方法,el或templatestring将被转换为renderfunctionif(!options.render){lettemplate=options.template//gettemplateif(template){if(typeoftemplate==='string'){if(template.charAt(0)==='#'){template=idToTemplate(template)/*伊斯坦布尔忽略if*/if(process.env.NODE_ENV!=='production'&&!template){warn(`Templateelementnotfoundorisempty:${options.template}`,this)}}}elseif(template.nodeType){template=template.innerHTML}else{if(process.env.NODE_ENV!=='production'){warn('invalidtemplateoption:'+template,this)}returnthis}}elseif(el){template=getOuterHTML(el)}if(template){/*伊斯坦布尔忽略if*/if(process.env.NODE_ENV!=='production'&&config.performance&&mark){mark('compile')}//将模板转换成渲染函数compileToFunctionsconst{render,staticRenderFns}=compileToFunctions(template,{outputSourceRange:process.env.NODE_ENV!=='production',shouldDecodeNewlines,shouldDecodeNewlinesForHref,delimiters:options.delimiters,comments:options.comments},this)options.render=renderoptions.staticRenderFns=staticRenderFns/*istanbul忽略if*/if(process.env.NODE_ENV!=='production'&&a议员;config.performance&&mark){mark('compileend')measure(`vue${this._name}compile`,'compile','compileend')}}}//这里调用的挂载就是上面的Cache挂载returnmount.call(this,el,hydrating)}这里的Vue还是通过import引入的,一路往上找,最后找到src\core\instance\index.js//Vue构造函数Vue(options){if(process.env.NODE_ENV!=='production'&&!(thisinstanceofVue)){warn('Vueisaconstructorandshouldbecalledwiththe`new`keyword')}//这是什么//initMixin给出Vue添加这个方法this._init(options)}//初始化//if(vm.$option.el){//$mount负责挂载//vm.$mount(vm.$option.el)//}initMixin(Vue)//初始化状态//Vue.prototype.$set=set//Vue.prototype.$delete=del//Vue.prototype.$watch=functionstateMixin(Vue)//event//$on,$emit,$once,$off和自己写的classbus没有太大区别//$emit触发t的事件eventsMixin(Vue)当前组件//_update!!!!!!!!!!!!!!!!//forceUpdate,destroylifecycleMixin(Vue)//render//nextTick//_render!!!!!!!!!!!renderMixin(Vue)导出默认Vue可以看出Vue的本质是函数。之所以用function而不是es6class,是因为以后很多API都会挂载在Vue函数原型上,比class更方便。Vue通过xxxMixin调用不同的目录下面的方法拼装成一个完整的Vue总结。package.json中script标签中的build命令用于查找项目源码入口,适用于其他源码阅读入口。Vue底层是构造函数,没有es类方便原型挂载和API扩展。模块内容