我还是不够了解Vue - 源码初探
Vue目录结构
src ├── compiler # 编译相关 ├── core # Vue核心 ├── platforms # 构建平台 ├── server # 服务端渲染 ├── sfc # 解析 .vue 后缀文件代码 ├── shared # 共享的工具代码和常量
从Vue
的目录可以看出,对于不同模块都区分的非常清楚,这样的设计模式
不仅利于开发和维护,也便于开发者阅读源码。目录下的每个模块都值得一读,重点从 Vue
的核心 core
入口开始。
Vue入口
# /src/core/index.js import Vue from './instance/index' import { initGlobalAPI } from './global-api/index' import { isServerRendering } from 'core/util/env' initGlobalAPI(Vue) Object.defineProperty(Vue.prototype, '$isServer', { get: isServerRendering }) Object.defineProperty(Vue.prototype, '$ssrContext', { get () { /* istanbul ignore next */ return this.$vnode && this.$vnode.ssrContext } }) Vue.version = '__VERSION__' export default Vue
主要做了以下事情:
- 引入
Vue
,并最终导出 - 调用
initGlobalAPI
,初始化全局API
- 劫持
Vue
原型上的$isServer
属性,修改其get
方法,判断是否为服务器渲染
// 其定义如下 export const isServerRendering = () => { if (_isServer === undefined) { /* istanbul ignore if */ if (!inBrowser && !inWeex && typeof global !== 'undefined') { // detect presence of vue-server-renderer and avoid // Webpack shimming the process _isServer = global['process'] && global['process'].env.VUE_ENV === 'server' } else { _isServer = false } } return _isServer }
- 修改
ssrContext
,判断是否为服务器渲染上下文
initGlobalAPI
# /src/core/global-api/index.js 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 // 2.6 explicit observable API Vue.observable = <T>(obj: T): T => { observe(obj) return obj } 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
的官方文档中的关于全局API
的内容都在这。
因为只是初步介绍,这里就不详述了,后续会在别的文章介绍。
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
的定义,它其实就是一个构造函数,我们平时在项目中 new Vue()
就是从这里开始的。
后续将会详细介绍Vue
初始化的过程,这里值得一提的是,Vue
并没有使用ES6 Class
的语法,而是通过扩展Vue
构造函数的prototype
,充分利用javascript
原型的设计实现了模块化,可以看到下面很多mixin
都是去扩展。就像前面说的,这样的代码设计非常利于阅读和维护。
相关推荐
源码zanqunet 2020-10-28
anchongnanzi 2020-09-21
CRMCRMCRMDS 2020-08-12
Cricket 2020-07-27
yuzhu 2020-11-16
85477104 2020-11-17
KANSYOUKYOU 2020-11-16
sjcheck 2020-11-03
怪我瞎 2020-10-28
gloria0 2020-10-26
王军强 2020-10-21
学习web前端 2020-09-28
QiaoranC 2020-09-25
安卓猴 2020-09-12
Macuroon 2020-09-11
kiven 2020-09-11
LittleCoder 2020-09-11
Cheetahcubs 2020-09-13
小焊猪web前端 2020-09-10