Vue源码思维导图------------Vue选项的合并之$options
本节将看下初始化中的$options:
Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// a uid
vm._uid = uid++
// a flag to avoid this being observed
vm._isVue = true
// 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 {
15 vm.$options = mergeOptions(
16 // merge Vue.option
17 resolveConstructorOptions(vm.constructor),
18 // new Vue(data) data for object
19 options || {},
20 // current instance
21 vm
22 )
}
………………………………
}
通过上边的代码可以看到 ,初始化时vm.$options被mergeOptions方法赋值。那么mergeOptions又做了哪些事情呢?
一. 检查组件名称是否符合要求( 1.是否由字母和-组成,并且以字母开头;2.检测你所注册的组件是否是内置的标签)
if (process.env.NODE_ENV !== 'production') {
checkComponents(child)
}
/**
* Validate component names
*/
function checkComponents (options: Object) {
for (const key in options.components) {
validateComponentName(key)
}
}
export function validateComponentName (name: string) {
if (!/^[a-zA-Z][\w-]*$/.test(name)) {
warn(
'Invalid component name: "' + name + '". Component names ' +
'can only contain alphanumeric characters and the hyphen, ' +
'and must start with a letter.'
)
}
if (isBuiltInTag(name) || config.isReservedTag(name)) {
warn(
'Do not use built-in or reserved HTML elements as component ' +
'id: ' + name
)
}
}
export const isBuiltInTag = makeMap('slot,component', true)
二. 规范化 (props, inject,directives)
1 normalizeProps(child, vm)
2 normalizeInject(child, vm)
3 normalizeDirectives(child)
/**
* Ensure all props option syntax are normalized into the
* Object-based format.
*/
function normalizeProps (options: Object, vm: ?Component) {
const props = options.props
if (!props) return
const res = {}
let i, val, name
if (Array.isArray(props)) {
i = props.length
while (i--) {
val = props[i]
if (typeof val === 'string') {
name = camelize(val)
res[name] = { type: null }
} else if (process.env.NODE_ENV !== 'production') {
warn('props must be strings when using array syntax.')
}
}
} else if (isPlainObject(props)) {
for (const key in props) {
val = props[key]
name = camelize(key)
res[name] = isPlainObject(val)
? val
: { type: val }
}
} else if (process.env.NODE_ENV !== 'production') {
warn(
`Invalid value for option "props": expected an Array or an Object, ` +
`but got ${toRawType(props)}.`,
vm
)
}
options.props = res
} /**
* Normalize all injections into Object-based format
*/
function normalizeInject (options: Object, vm: ?Component) {
const inject = options.inject
if (!inject) return
const normalized = options.inject = {}
if (Array.isArray(inject)) {
for (let i = 0; i < inject.length; i++) {
normalized[inject[i]] = { from: inject[i] }
}
} else if (isPlainObject(inject)) {
for (const key in inject) {
const val = inject[key]
normalized[key] = isPlainObject(val)
? extend({ from: key }, val)
: { from: val }
}
} else if (process.env.NODE_ENV !== 'production') {
warn(
`Invalid value for option "inject": expected an Array or an Object, ` +
`but got ${toRawType(inject)}.`,
vm
)
}
} /**
* Normalize raw function directives into object format.
*/
function normalizeDirectives (options: Object) {
const dirs = options.directives
if (dirs) {
for (const key in dirs) {
const def = dirs[key]
if (typeof def === 'function') {
dirs[key] = { bind: def, update: def }
}
}
}
}
三. Vue 选项的合并
const options = {}
let key
for (key in parent) {
mergeField(key)
}
for (key in child) {
if (!hasOwn(parent, key)) {
mergeField(key)
}
}
function mergeField (key) {
const strat = strats[key] || defaultStrat
options[key] = strat(parent[key], child[key], vm, key)
}

高清原图地址:https://github.com/huashuaipeng/vue--/blob/master/vm.%24options%20%EF%BC%88Vue%E5%AE%9E%E4%BE%8B%E4%B8%8A%E7%9A%84%24options%EF%BC%89.png
代码参考:
https://github.com/vuejs/vue/blob/dev/src/core/util/options.js
官网:
https://cn.vuejs.org/v2/api/#vm-options
Vue源码思维导图------------Vue选项的合并之$options的更多相关文章
- Vue2.0源码思维导图-------------Vue 初始化
上一节看完<Vue源码思维导图-------------Vue 构造函数.原型.静态属性和方法>,这节将会以new Vue()为入口,大体看下 this._init()要做的事情. fun ...
- Vue2.0源码思维导图-------------Vue 构造函数、原型、静态属性和方法
已经用vue有一段时间了,最近花一些时间去阅读Vue源码,看源码的同时便于理解,会用工具画下结构图. 今天把最近看到总结的结构图分享出来.希望可以帮助和其他同学一起进步.当然里边可能存在一些疏漏的,或 ...
- 前端-js进阶和JQ源码思维导图笔记
看不清的朋友右键保存或者新窗口打开哦!喜欢我可以关注我,还有更多前端思维导图笔记
- Vue源码分析(一) : new Vue() 做了什么
Vue源码分析(一) : new Vue() 做了什么 author: @TiffanysBear 在了解new Vue做了什么之前,我们先对Vue源码做一些基础的了解,如果你已经对基础的源码目录设计 ...
- [Vue源码]一起来学Vue双向绑定原理-数据劫持和发布订阅
有一段时间没有更新技术博文了,因为这段时间埋下头来看Vue源码了.本文我们一起通过学习双向绑定原理来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫 ...
- [Vue源码]一起来学Vue模板编译原理(一)-Template生成AST
本文我们一起通过学习Vue模板编译原理(一)-Template生成AST来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vu ...
- [Vue源码]一起来学Vue模板编译原理(二)-AST生成Render字符串
本文我们一起通过学习Vue模板编译原理(二)-AST生成Render字符串来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学V ...
- vue源码分析之new Vue过程
实例化构造函数 从这里可以看出new Vue实际上是使vue构造函数实例化,然后调用_init方法 _init方法,该方法在 src/core/instance/init.js 中定义 Vue.pro ...
- Vue源码详细解析:transclude,compile,link,依赖,批处理...一网打尽,全解析!
用了Vue很久了,最近决定系统性的看看Vue的源码,相信看源码的同学不在少数,但是看的时候却发现挺有难度,Vue虽然足够精简,但是怎么说现在也有10k行的代码量了,深入进去逐行查看的时候感觉内容庞杂并 ...
随机推荐
- Linux系统之-介绍,主要特性
Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和网络协议.它支持32位 ...
- Python(二)
函数Python的函数支持递归.默认参数值.可变参数,但不支持函数重载.为了增强代码的可读性,可以在函数后书写“文档字符串”(Documentation Strings,或者简称docstrings) ...
- 如何编写高性能的 javascript
一.Javascript代码执行效率1. DOM1.1 使用 DocumentFragment 优化多次 append说明:添加多个 dom 元素时,先将元素 append 到 DocumentFra ...
- Redis入门很简单之二【常见操作命令】
Redis入门很简单之二[常见操作命令] 博客分类: NoSQL/Redis/MongoDB redisnosql缓存 Redis提供了丰富的命令,允许我们连接客户端对其进行直接操作.这里简单介绍一 ...
- (4)C++ 复合类型-指针
篇幅长从 https://www.cnblogs.com/buchizaodian/p/11511256.html 提取出来 七.指针和自由存储空间 1.寻址运算符 * #include<io ...
- sql审核工具调研安装-sqlAdvisor和soar
sql审核工具调研 基于soar的sql审核查询平台: https://github.com/beiketianzhuang/data-platform-soar 1.美团工具sqlAdvisor工 ...
- c# networkcomms 3.0实现模拟登陆总结 转载https://www.cnblogs.com/zuochanzi/p/7039636.html
最近项目需要做一个客户查询状态系统,当前上位机缺少服务功能,于是找到了networkcomms 开源框架,作为项目使用. 最新版networkcomms 下载地址:https://github.com ...
- cocos2d之创建自己的场景类
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 1. 首先创建.h的头文件,然后在将一些图片声音素材加到resource文件夹内,最后在创建.cpp文件: .h头文件中创 ...
- Java中的注解到底是如何工作的?
作者:人晓 www.importnew.com/10294.html 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Over ...
- Data structure alignment by binary operation
在寫C的過程中,我們會很自然地以為,我連續宣告一堆大小不一的char array. 經過Complier之後這些char array未必是連續擺放.至於為什麼就要談到我們今天的主角了alignment ...