jsVue 2.5.1 源码学习 响应式入口observe

Posted yeujuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jsVue 2.5.1 源码学习 响应式入口observe相关的知识,希望对你有一定的参考价值。

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

 

以上是关于jsVue 2.5.1 源码学习 响应式入口observe的主要内容,如果未能解决你的问题,请参考以下文章

读Vue源码二 (响应式对象)

vue2源码学习-响应式原理

vue2源码学习-响应式原理

Vue源码学习

Vue3.0源码系列响应式原理 - Reactivity

Vue3.0源码系列响应式原理 - Reactivity