Vue源码思维导图------------Vue选项的合并之$options

本节将看下初始化中的$options:

 1   Vue.prototype._init = function (options?: Object) {
 2     const vm: Component = this
 3     // a uid
 4     vm._uid = uid++
 5
 6     // a flag to avoid this being observed
 7     vm._isVue = true
 8     // merge options
 9     if (options && options._isComponent) {
10       // optimize internal component instantiation
11       // since dynamic options merging is pretty slow, and none of the
12       // internal component options needs special treatment.
13       initInternalComponent(vm, options)
14     } 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       )
23     }
24 ………………………………
25 }

通过上边的代码可以看到 ,初始化时vm.$options被mergeOptions方法赋值。那么mergeOptions又做了哪些事情呢?

一. 检查组件名称是否符合要求(  1.是否由字母和-组成,并且以字母开头;2.检测你所注册的组件是否是内置的标签)

 1   if (process.env.NODE_ENV !== ‘production‘) {
 2     checkComponents(child)
 3   }
 4
 5 /**
 6  * Validate component names
 7  */
 8 function checkComponents (options: Object) {
 9   for (const key in options.components) {
10     validateComponentName(key)
11   }
12 }
13
14 export function validateComponentName (name: string) {
15   if (!/^[a-zA-Z][\w-]*$/.test(name)) {
16     warn(
17       ‘Invalid component name: "‘ + name + ‘". Component names ‘ +
18       ‘can only contain alphanumeric characters and the hyphen, ‘ +
19       ‘and must start with a letter.‘
20     )
21   }
22   if (isBuiltInTag(name) || config.isReservedTag(name)) {
23     warn(
24       ‘Do not use built-in or reserved HTML elements as component ‘ +
25       ‘id: ‘ + name
26     )
27   }
28 }
export const isBuiltInTag = makeMap(‘slot,component‘, true)

二.  规范化 (props, inject,directives)

1  normalizeProps(child, vm)
2  normalizeInject(child, vm)
3  normalizeDirectives(child)
 1 /**
 2  * Ensure all props option syntax are normalized into the
 3  * Object-based format.
 4  */
 5 function normalizeProps (options: Object, vm: ?Component) {
 6   const props = options.props
 7   if (!props) return
 8   const res = {}
 9   let i, val, name
10   if (Array.isArray(props)) {
11     i = props.length
12     while (i--) {
13       val = props[i]
14       if (typeof val === ‘string‘) {
15         name = camelize(val)
16         res[name] = { type: null }
17       } else if (process.env.NODE_ENV !== ‘production‘) {
18         warn(‘props must be strings when using array syntax.‘)
19       }
20     }
21   } else if (isPlainObject(props)) {
22     for (const key in props) {
23       val = props[key]
24       name = camelize(key)
25       res[name] = isPlainObject(val)
26         ? val
27         : { type: val }
28     }
29   } else if (process.env.NODE_ENV !== ‘production‘) {
30     warn(
31       `Invalid value for option "props": expected an Array or an Object, ` +
32       `but got ${toRawType(props)}.`,
33       vm
34     )
35   }
36   options.props = res
37 }
38
39 /**
40  * Normalize all injections into Object-based format
41  */
42 function normalizeInject (options: Object, vm: ?Component) {
43   const inject = options.inject
44   if (!inject) return
45   const normalized = options.inject = {}
46   if (Array.isArray(inject)) {
47     for (let i = 0; i < inject.length; i++) {
48       normalized[inject[i]] = { from: inject[i] }
49     }
50   } else if (isPlainObject(inject)) {
51     for (const key in inject) {
52       const val = inject[key]
53       normalized[key] = isPlainObject(val)
54         ? extend({ from: key }, val)
55         : { from: val }
56     }
57   } else if (process.env.NODE_ENV !== ‘production‘) {
58     warn(
59       `Invalid value for option "inject": expected an Array or an Object, ` +
60       `but got ${toRawType(inject)}.`,
61       vm
62     )
63   }
64 }
65
66 /**
67  * Normalize raw function directives into object format.
68  */
69 function normalizeDirectives (options: Object) {
70   const dirs = options.directives
71   if (dirs) {
72     for (const key in dirs) {
73       const def = dirs[key]
74       if (typeof def === ‘function‘) {
75         dirs[key] = { bind: def, update: def }
76       }
77     }
78   }
79 }

三. Vue 选项的合并

 1   const options = {}
 2   let key
 3   for (key in parent) {
 4     mergeField(key)
 5   }
 6   for (key in child) {
 7     if (!hasOwn(parent, key)) {
 8       mergeField(key)
 9     }
10   }
11   function mergeField (key) {
12     const strat = strats[key] || defaultStrat
13     options[key] = strat(parent[key], child[key], vm, key)
14   }

高清原图地址: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

原文地址:https://www.cnblogs.com/hsp-blog/p/9385904.html

时间: 2024-10-08 10:08:51

Vue源码思维导图------------Vue选项的合并之$options的相关文章

Vue源码思维导图-------------Vue 初始化

上一节看完<Vue源码思维导图-------------Vue 构造函数.原型.静态属性和方法>,这节将会以new Vue()为入口,大体看下 this._init()要做的事情. 1 function Vue (options) { 2 if (process.env.NODE_ENV !== 'production' && 3 !(this instanceof Vue) 4 ) { 5 warn('Vue is a constructor and should be ca

[Vue源码]一起来学Vue双向绑定原理-数据劫持和发布订阅

有一段时间没有更新技术博文了,因为这段时间埋下头来看Vue源码了.本文我们一起通过学习双向绑定原理来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vue模板编译原理(一)-Template生成AST 一起来学Vue模板编译原理(二)-AST生成Render字符串 一起来学Vue虚拟DOM解析-Virtual Dom实现和Dom-diff算法 这些文章统一放在我的git仓库:https://github.com/yzsun

[Vue源码]一起来学Vue模板编译原理(一)-Template生成AST

本文我们一起通过学习Vue模板编译原理(一)-Template生成AST来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vue模板编译原理(一)-Template生成AST 一起来学Vue模板编译原理(二)-AST生成Render字符串 一起来学Vue虚拟DOM解析-Virtual Dom实现和Dom-diff算法 这些文章统一放在我的git仓库:https://github.com/yzsunlei/javascrip

[Vue源码]一起来学Vue模板编译原理(二)-AST生成Render字符串

本文我们一起通过学习Vue模板编译原理(二)-AST生成Render字符串来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vue模板编译原理(一)-Template生成AST 一起来学Vue模板编译原理(二)-AST生成Render字符串 一起来学Vue虚拟DOM解析-Virtual Dom实现和Dom-diff算法 这些文章统一放在我的git仓库:https://github.com/yzsunlei/javascri

大白话Vue源码系列(01):万事开头难

阅读目录 Vue 的源码目录结构 预备知识 先捡软的捏 Angular 是 Google 亲儿子,React 是 Facebook 小正太,那咱为啥偏偏选择了 Vue 下手,一句话,Vue 是咱见过的最对脾气的 MVVM 框架.之前也使用过 knockout,angular,react 这些框架,但都没有让咱产生 follow 的冲动.直到见到 Vue,简直是一见钟情啊. Vue 的官方文档已经对 Vue 如何使用提供了最好的教程,建议 Vue 新手直接去官网学习,而不要在网上找些质量参差不齐的

Lifehacker评选 5款最好的思维导图软件

思维导图是一种革命性的思维工具,对于头脑风暴.项目规划或者将想法变为实际的步骤都是极佳的方式,更让人欣慰的是,现今多种多样的工具可以帮助大家构架思维导图.组织导图元素并保存下来便于后期使用.下面是Lifehacker网站根据网友投票选出的排名前5位最好的思维导图软件. 背景:此前在Lifehack网站发起了一轮投票,让网友选出他们认为最好的思维导图软件工具,根据统计得出结果,并将前五名展示如下: 1. Mindjet MindManager (Windows/Mac/iOS) Mindjet 不

曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享

写在前面的话&&About me 网上写spring的文章多如牛毛,为什么还要写呢,因为,很简单,那是人家写的:网上都鼓励你不要造轮子,为什么你还要造呢,因为,那不是你造的. 我不是要造spring,我只是想把自己学习spring的一些感想,一些心得说出来,希望大家看到有不对的地方,请一定不吝赐教. 说说我自己,13年小本毕业,软件工程专业,校招去了最近疯传的牢厂总部里待了2年,15年越狱出来,某落魄互联网公司(PC时代风头无两)待了1年,慨叹深圳买房之艰难,遂于16年底回蓉.趁着热血未冷

前端-Vue思维导图笔记

结构 看不清的朋友右键保存或者新窗口打开哦!喜欢我可以关注我,还有更多前端思维导图笔记 原文地址:https://www.cnblogs.com/buildweb/p/8277573.html

15分钟带你了解前端工程师必知的javascript设计模式(附详细思维导图和源码)

15分钟带你了解前端工程师必知的javascript设计模式(附详细思维导图和源码) 前言 设计模式是一个程序员进阶高级的必备技巧,也是评判一个工程师工作经验和能力的试金石.设计模式是程序员多年工作经验的凝练和总结,能更大限度的优化代码以及对已有代码的合理重构.作为一名合格的前端工程师,学习设计模式是对自己工作经验的另一种方式的总结和反思,也是开发高质量,高可维护性,可扩展性代码的重要手段. 我们所熟知的金典的几大框架,比如jquery, react, vue内部也大量应用了设计模式, 比如观察