一、 整體思路
1 首先是代碼的大體構造,先判斷引入代碼的環境,即對應amd 和cmd的處理
2 vue_init 需要借助 initMinxin ==>>> // 初始化選項1: 規範 2: 合并政策。
3 mergeOptions 選項合并 一個或者多個對象合并,并且生成一個新的對象
==> resloveConstructorOptions 傳回vm的optios 判斷是否是vue對象有可能是vue子類。不一定指向options。
parent 自定義的options的選項 child 使用者自定義的options
==> checkComonpents // 規範的檢測 validataComponentsName(key)
檢測component的名稱是否規範(不能使用内置标簽slot component 關于html的标簽名稱 svg的子類的名稱)
(規範:元件的名稱必須是字母或中橫線,必須由字母開頭)
isbuiltInTag 檢測是都是内置标簽 isReservedTag是否是html的标簽
===> makeMap 檢測key是否在makeMap裡面
==> mergeField 預設政策 // 以預設為優先。使用者定義為覆寫
defaultStrat(parent,chhild) 合并政策 child === undefined ? parent : child;
==> var config = { // 配置對象
// 内置對象自定義政策
optionMergeStrategies:{}
}
var strats = config.optionMergeStrategies;
4 Vue.options = {} vue的全局api
1 // 大體思路
2 // 1 首先是代碼的大體構造,先判斷引入代碼的環境,即對應amd 和cmd的處理
3 // 2 vue_init 需要借助 initMinxin // 初始化選項1: 規範 2: 合并政策。
4 // 3 mergeOptions 選項合并 一個或者多個對象合并,并且生成一個新的對象
5 // resloveConstructorOptions 傳回vm的optios 判斷是否是vue對象又k
6 // 有可能是vue子類。不一定指向options。
7 // parent 自定義的options的選項
8 // child 使用者自定義的options
9 /* checkComonpents // 規範的檢測 validataComponentsName(key)
10 檢測component的名稱是否規範(不能使用内置标簽slot component 關于html的标簽名稱 svg的子類的名稱)自稱)
11 (規範:元件的名稱必須是字母或中橫線,必須由字母開頭)
12 isbuiltInTag 檢測是都是内置标簽 isReservedTag是否是html的标簽
13 makeMap 檢測key是否在makeMap裡面
14 */
15 /* mergeField 預設政策 // 以預設為優先。使用者定義為覆寫
16 defaultStrat(parent,chhild)
17 child === undefined ? parent : child;
18 */
19 /*
20 var config = {
21 optionMergeStrategies:{}
22 }
23 var strats = config.optionMergeStrategies;
24 */
25 // 4 Vue.options = {} vue的全局api
26
27 (function(global,factory){
28 // 相容 cmd
29 typeof exports === 'object' && module !== 'undefined' ? module.exports = factory():
30 // Amd
31 typeof define === 'function' && define.amd ? define(factory) : global.Vue = factory();
32 })(this,function(){
33 var uip = 0;
34 function warn(string){
35 console.error('Vue Wran:' + string)
36 }
37
38 function resolveConstructorOptions(Con){
39 var options = Con.options;
40 // 判斷是否為vm的執行個體 或者是子類
41 return options
42 }
43 var hasOwnPropeerty = Object.prototype.hasOwnProperty
44 function hasOwn(obj , key){
45 return hasOwnPropeerty.call(obj,key)
46 }
47 function makeMap(str, expectsLoweraseC){
48 if(expectsLoweraseC){
49 str = str.toLowerCase()
50 }
51 var map = Object.create(null)
52 var list = str.split(',')
53 for(var i = 0 ; i < list.length; i++){
54 map[list[i]] = true
55 }
56 return function(key){
57 return map[key]
58
59 }
60 }
61 var isbuiltInTag = makeMap('slot,component',true)
62 var isHTMLTag = makeMap(
63 'html,body,base,head,link,meta,style,title,' +
64 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
65 'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
66 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
67 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
68 'embed,object,param,source,canvas,script,noscript,del,ins,' +
69 'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
70 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
71 'output,progress,select,textarea,' +
72 'details,dialog,menu,menuitem,summary,' +
73 'content,element,shadow,template,blockquote,iframe,tfoot'
74 );
75 var isSVG = makeMap(
76 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
77 'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
78 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
79 true
80 );
81 var isReservedTag = function(key){
82 return isHTMLTag(key) || isSVG(key)
83 }
84 function validataComponentName(key){
85 //檢測component 的自定義名稱是否合格
86 // 隻能是字母開頭或下劃線,必須是字母開頭
87 if(!(/^[a-zA-Z][\w-]*$/g.test(key))){
88 warn('元件的名稱必須是字母或中橫線,必須由字母開頭')
89 }
90 // 1. 不能為内置對象,2.不能是html ,和avg的内部标簽
91 if( isbuiltInTag(key) || isReservedTag(key)){
92 warn('不能為html标簽或者avg的内部标簽')
93 }
94 }
95 function checkComonpents(child){
96 for(var key in child.component){
97 validataComponentName(key)
98 }
99 }
100 // 配置對象
101 var config = {
102 // 自定義的政策
103 optionMergeStrategies:{}
104 }
105 var strats = config.optionMergeStrategies
106 strats.el = function(parent,child , key , vm){
107
108 if(!vm){
109 warn('選項'+key+'隻能在vue執行個體用使用')
110 }
111 return defaultStrat(parent,child , key , vm)
112 }
113 function defaultStrat(parent,child , key , vm){
114 return child === undefined ? parent :child ;
115 }
116 function mergeOptions(parent,child,vm){
117 var options = {}
118 // 檢測是component 是否是合法的
119
120 checkComonpents(child)
121
122 // console.log(parent, child)
123 for(key in parent){
124 magerField(key)
125 }
126 for(key in child){
127 if(!hasOwn(parent ,key)){ // parent 中循環過地方不進行循環
128 magerField(key) // ----忘記寫
129 }
130
131 }
132 // 預設合并政策
133 function magerField(key){
134 // 自定義政策 預設政策
135 // console.log(key)
136 var result = strats[key] || defaultStrat // ---忘記寫
137 options[key] = result(parent[key],child[key] , key , vm)
138 }
139 console.log(options)
140 return options
141 }
142 function initMinxin(options){
143 Vue.prototype._init = function(options){
144 var vm = this
145 // 記錄生成的vue執行個體對象
146 vm._uip = uip++ // //-------忘記寫
147
148 mergeOptions(resolveConstructorOptions(vm.constructor),options,vm)
149 }
150 }
151 function Vue(options){
152 // 安全機制
153 if(!(this instanceof Vue)){ //-------忘記寫
154 warn('Vue是一個構造函數,必須是由new關鍵字調用')
155 }
156 this._init(options)
157 }
158 initMinxin() // 初始化選項1: 規範 2: 合并政策。
159 Vue.options = {
160 components: {},
161 directives:{},
162 _bash: Vue
163 }
164 return Vue
165 })
1 <body>
2 <div id="app">
3 <huml></huml>
4 </div>
5 <script src="vue.js"></script>
6 <!-- <script src="vue2.5.1.js"></script> -->
7 <script type="text/javascript">
8 var componentA = {
9 el: "#app"
10 }
11 var vm = new Vue({
12 el:"#app",
13 data: {
14 message: "hello Vue",
15 key: "wodow"
16 },
17 components:{
18 huml: componentA
19 }
20
21 })
22 console.log(vm.$options)
23 </script>
24 </body>
以上僅為個人學習上的筆記,如有問題,歡迎評論。