当前位置: 首页 > Web前端 > vue.js

vue源码研究

时间:2023-04-01 00:15:37 vue.js

写的比较早。最近新部门的React项目需要多环境部署。参考了之前部门做的vue项目,顺便看看vue-cli-service的源码。在看源码的时候,我也看了Vue的源码。感觉很有意思。我打算仔细研究一下。这里我会继续更新我的经验~vue-cli-service多环境先在package.json中的script下添加如下内容:"scripts":{"serve":"vue-cli-serviceserve","serve:staging":"vue-cli-serviceserve--modestaging","serve:prod":"vue-cli-serviceserve--modeproduction","lint":"vue-cli-servicelint","格式”:“vue-cli-servicelint--formatter”,“检查”:“vue-cli-serviceinspect”,“build”:“vue-cli-servicebuild”,“build:staging”:“vue-cli-servicebuild--modestaging","build:prod":"vue-cli-servicebuild--modeproduction"},vue-cli-service源码在node_modules/@vue/cli-service/bin/vue-cli-service.js目录。vue-cli-service.js在14行加载了../lib/Service.js模块,这个模块在151行加载了serve.js模块serve.js在node_modules/@vue/cli-service/lib/commands/serve.js目录//serve.jsline50//检测环境,只在开发环境引入热更新插件//可以看到webpack配置链语法//configs只对dev有意义serverapi.chainWebpack(webpackConfig=>{if(process.env.NODE_ENV!=='production'&&process.env.NODE_ENV!=='test'){webpackConfig.devtool('cheap-module-eval-source-map')webpackConfig.plugin('hmr').use(require('webpack/lib/HotModuleReplacementPlugin'))//https://github.com/webpack/webpack/issues/6642//https://github.com/vuejs/vue-cli/issues/3539webpackConfig.output.globalObject(`(typeofself!=='undefined'?self:this)`)if(!process.env.VUE_CLI_TEST&&options.devServer.progress!==false){webpackConfig.plugin('progress').use(require('webpack/lib/ProgressPlugin'))}}})vue-cli和creat-react-app打开浏览器插件Vue中的openBrowser插件在node_modules/@vue/cli-shared-utils目录下打开index.js,可以看到如下内容:这里介绍openBrowser.js文件。该文件位于lib目录中。打开可以看到如下内容:这个插件和React中的openBrowser.js是一样的。React的相关代码如下:Vue检测数组变化。我们知道Vue2.x的响应机制是通过Object.defineProperty来实现的。此方法无法检测数组长度的变化。只有当整个数组被替换时才会触发setter。但是在实际开发中,调用数组的非变异方法(push、pop、shift、unshift、splice、sort、reverse)也可以触发视图更新,因为Vue封装了这些方法。源码在node_modules/vue/src/core/observer/array.jsimport{def}from'../util/index'constarrayProto=Array.prototypeexportconstarrayMethods=Object.create(arrayProto)constmethodsToPatch=['push','pop','shift','unshift','splice','sort','reverse']/***拦截变异方法并发出事件*/methodsToPatch.forEach(function(method){//缓存原始方法constoriginal=arrayProto[method]def(arrayMethods,method,functionmutator(...args){constresult=original.apply(this,args)constob=this.__ob__让插入开关(方法){case'push':case'unshift':inserted=argsbreakcase'splice':inserted=args.slice(2)break}if(inserted)ob.observeArray(inserted)//通知变化ob.dep.notify()返回结果})})其中def()的作用就是重新定义对象属性的值,代码在util/lang.js/***定义一个属性。*/exportfunctiondef(obj:Object,key:string,val:any,enumerable?:boolean){Object.defineProperty(obj,key,{value:val,enumerable:!!enumerable,writable:true,configurable:true})}def(arrayMethods,method,function(){})这个函数可以看做arrayMethods[method]=functionmutator(){}具体见下面的例子:constpush=Array.prototype.push;Array.prototype.push=functionmutator(...arg){constresult=push.apply(this,arg);做一点事();returnresult}functiondoSomething(){console.log('dosomething');}第一步保存原数组方法,先找到实际值注意:要触发视图更新,需要替换/变异整个数组,或者应该使用非突变的方法。直接用下标或长度修改数组是检测不到的。$nextTick的原理Vue的核心源码在node_modules/vue/src/core目录下。该目录还包括vdom、observer和global-api的实现。你可以在node_modules/vue/src/core/util/next-tick.js目录下查看$nextTick的源码