vue源码解析(一)
前段时间用vue3开发了几个项目,由于vue3有蛮多新特性的所以还是有必要去学习一下vue3的源码,在此之前呢,先来复习一遍vue2的源码吧。下面我会分为几部分来解剥vue的底层代码。
1. 源码构建
"scripts": {
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
······
"build": "node scripts/build.js",
"build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
"build:weex": "npm run build -- weex",
······
}
执行build后就回去找构建入口文件 scripts/build.js
let builds = require('./config').getAllBuilds()
// filter builds via command line arg
if (process.argv[2]) { // 这里是判断构建是否有其他项
const filters = process.argv[2].split(',')
builds = builds.filter(b => {
return filters.some(f => b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1)
})
} else {
// filter out weex builds by default
builds = builds.filter(b => {
return b.output.file.indexOf('weex') === -1
})
}
build(builds)
在build.js里我们发现他取到了config.js里的builds,并且做了一层筛选,用于构建出不同的代码块。我们接着跟着逻辑走,builds里会通过函数resolve去找到对应的入口文件,它们都会被构建成dest里的出口文件
const builds = {
// Runtime only (CommonJS). Used by bundlers e.g. Webpack & Browserify
'web-runtime-cjs-dev': {
entry: resolve('web/entry-runtime.js'),
dest: resolve('dist/vue.runtime.common.dev.js'),
format: 'cjs',
env: 'development',
banner
},
········
}
也就是说,执行命令构建打包后,entry会通过resolve函数会根据内容找到对应的代码块,并输出给dest。 最终会在 dist 目录下生成对应的js文件。
构建总结
通过上面的部分学习我们了解到了vue底层构建打包,也知道了不同作用和功能的 Vue.js 它们对应的入口以及最终编译生成的 JS 文件。
初始化
根据上文我们可得知vue的代码是在src/core/index.js
中的,根据它我们找到了存放vue地方src/core/instance/index.js
import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/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
原来vue实际上就是一个用 Function
实现的类,所以我们每次都需要new Vue
来实例化,里面还有很多带xxxMixin的函数,并用了vue当参数,这里是在vueprototype
上挂载一些方法。
initGlobalAPI在vue初始化时挂载了我们常用的一些方法 如nextTick,vue的全局API都可以在这里找到
export function initGlobalAPI (Vue: GlobalAPI) {
// config
const configDef = {}
configDef.get = () => config
if (process.env.NODE_ENV !== 'production') {
configDef.set = () => {
warn(
'Do not replace the Vue.config object, set individual fields instead.'
)
}
}
Object.defineProperty(Vue, 'config', configDef)
// exposed util methods.
// NOTE: these are not considered part of the public API - avoid relying on
// them unless you are aware of the risk.
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
Vue.options = Object.create(null)
ASSET_TYPES.forEach(type => {
Vue.options[type + 's'] = Object.create(null)
})
// this is used to identify the "base" constructor to extend all plain-object
// components with in Weex's multi-instance scenarios.
Vue.options._base = Vue
extend(Vue.options.components, builtInComponents)
initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)
}
初始化总结
到这里vue初始化基本就结束了,相信看完了大家对vue都有一些基本的认知了,文中还有很多东西我们会放到后面慢慢学习。
尾言
这是我第一次在掘金发文章,因为之前在知乎专心回答过一些问题,我发现写一些文章不仅能知道自己对知识的掌握能力还可以巩固知识以及发现新的知识点。所以我就写下了这一篇文章,第一次发文写的也许不是很友好,后续会慢慢迭代的。这篇文章参考了 vue技术揭秘。写的很好,感兴趣可以去看一看,我写文章的目的呢就是用来巩固知识点的。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!