码迷,mamicode.com
首页 > 编程语言 > 详细

【js】vue 2.5.1 源码学习 (九) 响应数组对象的变

时间:2019-07-11 12:53:54      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:get   rtc   item   items   make   asc   tle   apply   数值   

大体思路(八)
本节内容:
1.Observe 如何响应数组的变化
代理原型 数组变异方法
shell cacheArrProto methods
新添加的数组需要加到显示系统里面,拦截 push等的方法
swith(method){
  case:"push"/"unshift" : 存储东西}
  observer.prototype.observeArray = function(items){
  observe(item[i])
}
observe
  ==> var augment = hasProto ? protoAugment : copyAugment ;
  ==> augment(value, shell)

protoAugment(target,shell) ==> 非ie
target._proto = shell
copyAugment(target,src,arrayKeys) ==> ie
  ==> def(target,key,src[key])
vue.js代码如下
技术图片
  1 //  大体思路(八)
  2 //  本节内容:
  3 //  1.Observe 如何响应数组的变化
  4 //      代理原型  数组变异方法  
  5 //      shell cacheArrProto methods 
  6 //      新添加的数组需要加到显示系统里面,拦截 push等的方法
  7 //      swith(method){
  8 //         case:"push"/"unshift"  : 存储东西}
  9 //      observer.prototype.observeArray = function(items){  
 10 //            observe(item[i])
 11 //     }
 12 // observe 
 13 //  ==>  var augment =   hasProto  ? protoAugment : copyAugment ;
 14 //  ==>  augment(value, shell)
 15 
 16 //  protoAugment(target,shell) ==> 非ie  
 17 //  target._proto = shell
 18 //  copyAugment(target,src,arrayKeys)  ==> ie 
 19 //     ==>  def(target,key,src[key])
 20 
 21 
 22 
 23 
 24 
 25 (function (global, factory) {
 26     // 兼容 cmd  
 27     typeof exports === ‘object‘ && module !== ‘undefined‘ ? module.exports = factory() :
 28     // Amd
 29     typeof define === ‘function‘ && define.amd ? define(factory) : global.Vue = factory();
 30 })(this, function () {
 31     var uip = 0;
 32 
 33     function warn(string) {
 34         console.error(‘Vue Wran:‘ + string)
 35     }
 36 
 37     function warnNonpresent(target, key) {
 38         warn(‘属性方法‘ + key + ‘未在实例对象上定义,渲染功能正在尝试访问这个不存在的属性!‘)
 39     }
 40 
 41     function resolveConstructorOptions(Con) {
 42         var options = Con.options;
 43         // 判断是否为vm的实例 或者是子类
 44         return options
 45     }
 46     var hasOwnPropeerty = Object.prototype.hasOwnProperty
 47    
 48     function hasOwn(obj, key) {
 49         return hasOwnPropeerty.call(obj, key)
 50     }
 51 
 52     function makeMap(str, expectsLoweraseC) {
 53         if (expectsLoweraseC) {
 54             str = str.toLowerCase()
 55         }
 56         var map = Object.create(null)
 57         var list = str.split(‘,‘)
 58         for (var i = 0; i < list.length; i++) {
 59             map[list[i]] = true
 60         }
 61         return function (key) {
 62             return map[key]
 63 
 64         }
 65     }
 66     var isbuiltInTag = makeMap(‘slot,component‘, true)
 67     var isHTMLTag = makeMap(
 68         ‘html,body,base,head,link,meta,style,title,‘ +
 69         ‘address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,‘ +
 70         ‘div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,‘ +
 71         ‘a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,‘ +
 72         ‘s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,‘ +
 73         ‘embed,object,param,source,canvas,script,noscript,del,ins,‘ +
 74         ‘caption,col,colgroup,table,thead,tbody,td,th,tr,‘ +
 75         ‘button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,‘ +
 76         ‘output,progress,select,textarea,‘ +
 77         ‘details,dialog,menu,menuitem,summary,‘ +
 78         ‘content,element,shadow,template,blockquote,iframe,tfoot‘
 79     );
 80     var isSVG = makeMap(
 81         ‘svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,‘ +
 82         ‘foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,‘ +
 83         ‘polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view‘,
 84         true
 85     );
 86    
 87     var ASSET_TYPES = [
 88         ‘component‘,
 89         ‘directive‘,
 90         ‘filter‘
 91     ];
 92 
 93     var LIFECYCLE_HOOKS = [
 94         ‘beforeCreate‘,
 95         ‘created‘,
 96         ‘beforeMount‘,
 97         ‘mounted‘,
 98         ‘beforeUpdate‘,
 99         ‘updated‘,
100         ‘beforeDestroy‘,
101         ‘destroyed‘,
102         ‘activated‘,
103         ‘deactivated‘,
104         ‘errorCaptured‘
105     ];
106     var methods = [
107         ‘push‘,
108         ‘pop‘,
109         ‘shift‘,
110         ‘unshift‘,
111         ‘splice‘,
112         ‘sort‘,
113         ‘reverse‘
114     ];
115     var cacheArrProto = Array.prototype
116     var shell = Object.create(Array.prototype)
117     methods.forEach(function(method){
118         var cacheMethod = cacheArrProto[method]
119         def(shell,method,function(){
120             var args = []
121             var len = arguments.length
122             while(len--) args[len] = arguments[len]
123             var result = cacheMethod.apply(this,args)  // 调用原来的方法
124             var ob = this.__ob__;
125             var inserted ;
126             switch(method){
127                 case ‘push‘ : 
128                 case ‘unshift‘: 
129                 inserted = args
130                 case ‘splice‘: 
131                 inserted = args.slice(2);
132             }
133             if(inserted){
134                 ob.observeArray(inserted)  // 奖新加入的数组加入到显示系统里面。
135             }
136             ob.dep.notify();
137             return result;  //返回数组原来的答案,
138         })
139     })
140     var arrayKeys = Object.getOwnPropertyNames(shell)
141     var hasProto = ‘__proto__‘ in {}
142     var noop = function () {}
143     var isReservedTag = function (key) {
144         return isHTMLTag(key) || isSVG(key)
145     }
146     // 检测data的属性名称是否为 _ 或者$ 开始的,这些的话是vue的其他属性的值。
147     function isReserved(key) {
148         var c = key.charCodeAt(0)
149         return c === 0x24 || c === 0x5F
150     }
151     // 检查是否为对象
152     function isObject(val) {
153         return val !== null && typeof val === ‘object‘
154     }
155 
156     function validataComponentName(key) {
157         //检测component 的自定义名称是否合格 
158         // 只能是字母开头或下划线,必须是字母开头
159         if (!(/^[a-zA-Z][\w-]*$/g.test(key))) {
160             warn(‘组件的名称必须是字母或中横线,必须由字母开头‘)
161         }
162         // 1. 不能为内置对象,2.不能是html ,和avg的内部标签
163         if (isbuiltInTag(key) || isReservedTag(key)) {
164             warn(‘不能为html标签或者avg的内部标签‘)
165         }
166     }
167 
168     function checkComonpents(child) {
169         for (var key in child.components) {
170             validataComponentName(key)
171         }
172     }
173     // 配置对象
174     var config = {
175         // 自定义的策略
176         optionMergeStrategies: {}
177     }
178     var strats = config.optionMergeStrategies
179     strats.el = function (parent, child, key, vm) {
180 
181         if (!vm) {
182             warn(‘选项‘ + key + ‘只能在vue实例用使用‘)
183         }
184         return defaultStrat(parent, child, key, vm)
185     }
186 
187     function mergeData(to, form) {
188         // 终极合并
189         if (!form) {
190             return to
191         }
192         // 具体合并。  
193     }
194 
195     function mergeDataorFn(parentVal, childVal, vm) {
196         // 合并 parentVal childVal  都是函数
197         if (!vm) {
198             if (!childVal) {
199                 return parentVal
200             }
201             if (!parentVal) {
202                 return childVal
203             }
204             return function mergeDataFn(parentVal, childVal, vm) { //只是一个函数   什么样的情况下调用 加入响应式系统 
205                 // 合并子组件对应的data 和   父组件对应的data
206                 return mergeData(
207                     typeof parentVal === ‘function‘ ? parentVal.call(this, this) : parentVal, // -----忘记写
208                     typeof childVal === ‘function‘ ? childVal.call(this, this) : childVal) // -----忘记写
209             }
210         } else { // vue实例
211             return function mergeInstanceDataFn() { //只是一个函数   什么样的情况下调用 加入响应式系统 
212                 var InstanceData = typeof childVal === ‘function‘ ? childVal.call(vm, vm) : childVal; // -----忘记写
213                 var defaultData = typeof parentVal === ‘function‘ ? parentVal.call(vm, vm) : parentVal; // -----忘记写
214                 if (InstanceData) {
215                     return mergeData(InstanceData, defaultData)
216                 } else { // -----忘记写
217                     return defaultData
218                 }
219 
220             }
221         }
222     }
223     strats.data = function (parent, child, key, vm) {
224         if (!vm) {
225             // console.log(typeof child === ‘function‘)
226             if (child && !(typeof child === ‘function‘)) {
227                 warn(‘data必须返回是一个function‘)
228             }
229             return mergeDataorFn(parent, child)
230         }
231         return mergeDataorFn(parent, child, vm)
232     }
233     // 生命周期策略的合并,值等于一个function 如果是有两个,放到一个数组里面。
234     function mergeHook(parentVal, childVal, key, vm) {
235         // console.log(key)
236         // console.log(parentVal.concat(childVal) )
237         return childVal ? parentVal ? parentVal.concat(childVal) :
238             Array.isArray(childVal) ? childVal : [childVal] : parentVal
239     }
240     LIFECYCLE_HOOKS.forEach(function (key) {
241         strats[key] = mergeHook
242     });
243     // 检测是否为object
244     function isPlainObject(obj) {
245         return Object.prototype.toString.call(obj) === ‘[object Object]‘
246     }
247 
248     function assetObjectType(obj) {
249         if (!isPlainObject(obj)) {
250             warn(‘选项的值‘ + obj + ‘无效:必须是一个对象的‘)
251         }
252     }
253     // 对parent实现链式调用。
254     function extend(to, form) {
255         for (key in form) {
256 
257             to[key] = form[key]
258         }
259         return to
260     }
261     // 实现Assets 的策略合并  conmponents  filter  diretive   
262     function mergeAssets(parentVal, childVal, key, vm) {
263         var parent = Object.create(parentVal || null) // 保证子类的每个值的指向都是一个新的object。否则回出现相互引用的现象。
264         if (childVal) {
265             assetObjectType(childVal)
266             return extend(parent, childVal)
267         }
268         return parent
269     }
270     ASSET_TYPES.forEach(function (key) {
271         strats[key + ‘s‘] = mergeAssets
272     })
273     // 实现watch的策略和并,将相同的属性放到一个数组里面。
274     strats.watch = function (parentVal, childVal, key, vm) {
275         if (!childVal) {
276             return Object.create(parentVal)
277         }
278         var res = {}
279         res = extend(res, parentVal)
280         for (var key in childVal) {
281             var parent = res[key]
282             var child = childVal[key]
283             res[key] = parent ? Array.isArray(parent) ? parent.concat(child) : [parent].concat(child) :
284                 Array.isArray(child) ? child : [child];
285         }
286         return res
287     }
288     // 实现props指令的合并策略
289     strats.props = function (parentVal, childVal, key, vm) {
290         if (!childVal) {
291             return parentVal
292         }
293         var res = Object.create(null)
294         extend(res, parentVal)
295         if (childVal) {
296             extend(res, childVal)
297         }
298         return res
299     }
300 
301     function defaultStrat(parent, child, key, vm) {
302         return child === undefined ? parent : child;
303     }
304     var cmalizeRE = /-(\w)/g
305 
306     function camelize(val) {
307         return val.replace(cmalizeRE, function (c, m) {
308             return m ? m.toUpperCase() : ""
309         })
310     }
311 
312     function normalizeProps(options) {
313         var props = options.props
314         if (!props) {
315             return
316         }
317         var i, val, name
318         var res = {}
319         if (Array.isArray(props)) {
320             i = props.length
321             while (i--) {
322                 val = props[i]
323                 if (toString.call(val) === ‘[object String]‘) {
324                     name = camelize(val)
325                     res[name] = {
326                         type: null
327                     }
328                 } else {
329                     warn(‘使用数组愈发时props成员‘ + val + ‘必须时一个数组‘)
330                 }
331 
332 
333             }
334         } else if (isPlainObject(props)) {
335             for (var key in props) {
336                 val = props[key]
337                 name = camelize(key)
338                 res[name] = isPlainObject(val) ? val : {
339                     type: val
340                 }
341             }
342         } else {
343             warn(‘选项props的值必须是一个对象或者是数组‘)
344         }
345         options.props = res
346     }
347 
348     function mormalizeDirectives(options) {
349         var dir = options.directives
350         var res = {}
351         if (!dir) {
352             return
353         }
354         if (dir) {
355             for (var key in dir) {
356                 var val = dir[key]
357                 var name = camelize(key)
358                 if (isPlainObject(val)) {
359                     res[name] = val
360                 }
361                 if (toString.call(val) === ‘[object Function]‘) {
362                     res[name] = {
363                         bind: val,
364                         upata: val
365                     }
366                 }
367             }
368         }
369         options.directives = res
370 
371     }
372 
373     function mergeOptions(parent, child, vm) {
374         var options = {}
375         // 检测是component 是否是合法的  
376         checkComonpents(child)
377         // 规范props 
378         normalizeProps(child)
379         // 规范 dirctives 
380         mormalizeDirectives(child)
381 
382         // console.log(parent, child)
383         for (key in parent) {
384             magerField(key)
385         }
386         for (key in child) {
387             if (!hasOwn(parent, key)) { // parent 中循环过地方不进行循环
388                 magerField(key) // ----忘记写
389             }
390 
391         }
392         // 默认合并策略
393         function magerField(key) {
394             // 自定义策略  默认策略 
395             // console.log(key)
396             var result = strats[key] || defaultStrat // ---忘记写
397             options[key] = result(parent[key], child[key], key, vm)
398         }
399         // console.log(options)
400         return options
401     }
402 
403     var allowedGlobals = makeMap(
404         ‘Infinity,undefined,NaN,isFinite,isNaN,‘ +
405         ‘parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,‘ +
406         ‘Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,‘ +
407         ‘require‘ // for Webpack/Browserify
408     );
409 
410     function isNative(Ctor) {
411         return typeof Ctor !== undefined && /native code/.test(toString.call(Ctor))
412     }
413     var hasproxy = typeof Proxy !== undefined && isNative(Proxy)
414     var hasHeadler = {
415         has: function (target, key) {
416             var val = key in target
417             // key 是否是全局对象 或者内置方法 _
418             var isAllowed = allowedGlobals(key) || (typeof key === ‘string‘ && key.charAt(0) === ‘_‘)
419             if (!val && !isAllowed) {
420                 warnNonpresent(target, key)
421             }
422             return val || !isAllowed
423         }
424     }
425     var getHeadler = {
426         get: function (target, key) {
427             if (typeof key === ‘string‘ && !(key in target)) {
428                 warnNonpresent(target, key)
429             }
430             return target[key]
431         }
432     }
433 
434     // 数据代理
435     function initProxy(vm) {
436         var options = vm.$options
437         // 判断是否是es6 是否存在Proxy
438         if (hasproxy) {
439             // 渲染函数拦截那些操作。 1. has 查询 2. get 或者
440             var headler = options.render && options.render._withStripeed ?
441                 getHeadler :
442                 hasHeadler;
443             vm._renderPorxy = new proxy(vm, headler)
444         } else {
445             // 如果不支es6  Proxy
446             vm._renderPorxy = vm
447         }
448     }
449 
450 
451     // 初始化当前实例的$children 和$parent 的指向
452     function initLifeCycle(vm) {
453         var options = vm.$options
454         // 当前组件 父实例 
455         var parent = options.parent // 组件的实例对象
456         // 是否抽象组件 
457         if (parent && !parent.abstrat) {
458             while (parent.$options.abstrat && parent.$parent) {
459                 parent = parent.$options.parent
460             }
461             parent.$children.push(vm)
462         }
463         vm.$parent = parent
464         vm.$root = parent ? parent.$root : vm;
465 
466         vm.$children = [];
467         vm.$refs = {};
468 
469         vm._watcher = null;
470         vm._inactive = null;
471         vm._directInactive = false;
472         vm._isMounted = false; // 是否挂载 
473         vm._isDestroyed = false; // 是否销毁
474         vm._isBeingDestroyed = false; // 是否正在销毁
475 
476     }
477 
478     function callHook(vm, hook) {
479         var options = vm.$options
480         var obj = options[hook]
481         if (obj) {
482             for (var i = 0; i < obj.length; i++) {
483                 obj[i].call(vm)
484             }
485         }
486 
487     }
488 
489     function getData(data, vm) {
490         return data.call(vm, vm)
491     }
492 
493     //共享的访问器对象
494     var sharedProperty = {
495         enumerable: true,
496         configurable: true,
497         get: noop,
498         set: noop
499     };
500 
501     function proxy(vm, data, key) {
502 
503         sharedProperty.get = function () {
504                 // console.log("我监听到你访问了我")
505                 return this[data][key]
506             },
507             sharedProperty.set = function (newVal) {
508                 console.log("我设置了data的值" + key + "==" + newVal)
509                 this[data][key] = newVal
510 
511             }
512         Object.defineProperty(vm, key, sharedProperty)
513     }
514 
515     function initData(vm) {
516         var opts = vm.$options
517         var data = vm.$options.data
518         // 通过之前strats 里面合成好的数据,data是一个function ,为了独立数据调用的空间。拿到data的值。
519         data = vm._data = typeof data === ‘function‘ ? getData(data, vm) : data || {}
520         if (!isPlainObject(data)) {
521             data = {}
522             warn(‘data选项应该是object对象‘)
523         }
524         // data methods props 里面属性名称不能相同
525         var props = opts.props
526         var methods = opts.methods
527         for (let key in data) {
528             if (props && hasOwn(props, key)) {
529                 warn("props " + key + "选项已经定义为data的属性.")
530             } else if (methods && hasOwn(methods, key)) {
531                 warn("methods: " + key + "选项已经定义为data的属性.")
532             } else if (!isReserved(key)) {
533                 proxy(vm, "_data", key)
534             }
535 
536         }
537         observe(data, true)
538     }
539     var shouldObserve = true
540     var toggleObserving = function (value) {
541         shouldObserve = value
542     }
543 
544     function Dep() {
545         this.subs = []
546     }
547     Dep.prototype.addSub = function (sub) {
548         this.subs.push(sub)
549     }
550     Dep.prototype.depend = function () {
551         console.log("收集依赖"); //Watch 观察者
552     }
553     Dep.prototype.notify = function () {
554         var subs = this.subs.slice()
555         for (var i = 0; i < subs.length; i++) {
556             subs[i].updata() // 数据更新的操作   Watch
557         }
558     }
559     Dep.target = null
560 
561     function def(obj, key, val) { // data._ob_  实例对象 指向 Observer
562         Object.defineProperty(obj, key, {
563             value: val,
564             enumerable: false, //不可枚举
565             configrable: true
566         })
567     }
568 
569     function Observe(value) {
570         this.value = value;
571         this.vmCount = 0;
572         this.dep = new Dep() //回调列表 依赖在什么情况调用 
573         def(value, ‘_ob_‘, this)
574         if(Array.isArray(value)){
575             var augment = hasProto ?  protoAugment : copyAugment ;
576             augment(value,shell,arrayKeys)
577         }else{
578             this.walk(value)
579         }
580        
581     }
582     function protoAugment(target,src){
583         target.__proto__ = src
584     }
585     function copyAugment(target,src,keys){
586         for(var i =0, j=keys.length; i<j; i++){
587             var key = keys[i];
588             def(target, key, src[key]);
589         }
590         console.log(target)
591     }
592     // 加入响应式系统   添加   setter  getter
593     function defindReactive(obj, key, val, shallow) {
594         var dep = new Dep() // 收集依赖  回调列表
595         var property = Object.getOwnPropertyDescriptor(obj, key)
596         var getter = property && property.get
597         var setter = property && property.set
598         // getter 和 setter 都不存在。或者都存在则为 true ===》 (!getter || setter)
599         // console.log((!getter || setter),arguments)
600         if ((!getter || setter) && arguments.length === 2) {
601             val = obj[key] // 深度观测  
602         }
603         var childOb = !shallow && observe(val)
604         Object.defineProperty(obj, key, {
605             get: function () {
606                 var value = getter ? getter.call(obj) : val
607                 if (Dep.target) {
608                     dep.depend()  // 收集依赖
609                     if (childOb) {
610                         childOb.dep.depend()  // 收集依赖
611                     }
612                 }
613                 return value
614             },
615             set: function (newVal) {
616                 var value = setter ? setter.call(obj) : val
617                 // is NaN !== NaN
618                 if (newVal === value || (value !== value && newVal !== newVal)) {
619                     return
620                 }
621                 if (setter) {
622                     setter.call(obj, newVal)
623                 } else {
624                     val = newVal
625                 }
626                 console.log(‘我监听到data变化‘ + newVal)
627                 // 如果改变的新值为 object 或者Array 就在进行深度检测,递归。
628                 childOb = !shallow && observe(val)
629                 dep.notify() //通知依赖更新
630 
631             }
632         })
633     }
634     Observe.prototype.walk = function (value) {
635         var keys = Object.keys(value)
636         for (var i = 0; i < keys.length; i++) {
637             defindReactive(value, keys[i])
638         }
639     }
640     Observe.prototype.observeArray = function(items){
641         items.forEach(function(item){
642             observe(item)
643         })
644     }
645     // 响应式系统
646     function observe(value, asRootData) {
647         var ob
648         if (!isObject(value)) {
649             return;
650         }
651         if(hasOwn(value,‘_ob_‘) && value._ob_ instanceof Observe){
652             ob= value._ob_
653 
654         }else if (shouldObserve && (Array.isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue) {
655             ob = new Observe(value)
656         }
657         if (ob && asRootData) {
658             ob.vmCount++
659         }
660 
661         return ob
662     }
663 
664     function initState(vm) {
665         var opts = vm.$options
666         // 初始化props
667         if (opts.props) {
668             initProps(vm, opts.props)
669         }
670         // 初始化methods
671         if (opts.methods) {
672             initMethods(vm, opts.methods)
673         }
674         // 初始化computed
675         if (opts.computed) {
676             initComputed(vm, opts.computed)
677         }
678         // 初始化data 如果存在就initData
679         if (opts.data) {
680             initData(vm)
681         } else {
682             // 放在响应式系统里面
683             observe(vm._data = {}, true)
684         }
685     }
686 
687     function initMinxin(options) {
688         Vue.prototype._init = function (options) {
689             var vm = this
690             // 记录生成的vue实例对象 
691             vm._uip = uip++ //   //-------忘记写
692             // 是否可扩展
693             vm.is_Vue = true;
694             //合并选项
695             vm.$options = mergeOptions(resolveConstructorOptions(vm.constructor), options, vm)
696             // // 初始化数值代理
697             initProxy(vm)
698             // 初始化当前实例的$children 和$parent 的指向
699             initLifeCycle(vm)
700             // 调用beforeCreate 的钩子函数
701             callHook(vm, ‘beforeCreate‘)
702             // 初始化数据
703             initState(vm)
704         }
705     }
706 
707     function Vue(options) {
708         // 安全机制
709         if (!(this instanceof Vue)) { //-------忘记写
710             warn(‘Vue是一个构造函数,必须是由new关键字调用‘)
711         }
712         this._init(options)
713     }
714     initMinxin() //  初始化选项1: 规范 2: 合并策略。
715     Vue.options = {
716         components: {
717             transtions: {},
718             keepAlive: {},
719             solt: {},
720             transtionsGroup: {}
721         },
722         directives: {},
723         _bash: Vue
724     }
725 
726     function initExend(Vue) {
727         Vue.extend = function (extendOptions) {
728             extendOptions = extendOptions || {} // -----忘记写
729             var Super = this
730             var Child = function VueComponent(options) {
731                 this._init(options)
732             }
733             Child.prototype = Object.create(Super.prototype)
734             Child.prototype.constructor = Child // 改变constructor 的指向
735             Child.options = mergeOptions(Super.options, extendOptions)
736             // 子类继承父类的静态方法。
737             Child.extend = Vue.extend
738             // console.log(new Child({}))
739             return Child
740         }
741     }
742     initExend(Vue)
743     return Vue
744 })
View Code

html代码

技术图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>第八课</title>
 8 </head>
 9 <body>
10     <div id="app">
11         <huml></huml>
12      
13     </div>
14     <script src="vue.js"></script>
15     <!-- <script src="vue2.5.1.js"></script> -->
16     <script type="text/javascript">
17         var componentA = {
18             el: "#app"
19         }
20         var vm = new Vue({
21             el:"#app",
22             data: { 
23                 message: "hello Vue",
24                 key: "wodow",
25                 test: 1,
26                 list: {
27                     b:1
28                 },
29                 aa:{
30                     b: [1,2,3]
31                 }
32             },
33             beforeCreate: function(){
34                 console.log(‘我钩子函数beforeCreate‘)
35             },
36             components:{
37                 humle: componentA
38             } 
39         })
40         vm.test = 2;
41         // console.log(vm.aa)
42     </script>
43 </body>
44 </html>
View Code

 

【js】vue 2.5.1 源码学习 (九) 响应数组对象的变

标签:get   rtc   item   items   make   asc   tle   apply   数值   

原文地址:https://www.cnblogs.com/yeujuan/p/11169055.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!