You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/*初始化data*/functioninitData(vm: Component){/*得到data数据*/letdata=vm.$options.data/*遍历data对象*/constkeys=Object.keys(data)constprops=vm.$options.propsleti=keys.length//遍历data中的数据while(i--){if(props&&hasOwn(props,keys[i])){process.env.NODE_ENV!=='production'&&warn(`The data property "${keys[i]}" is already declared as a prop. `+`Use prop default value instead.`,vm)}}// observe data/*通过observe实例化Observe对象,开始对数据进行绑定* asRootData用来根数据,用来计算实例化根数据的个数* 下面会进行递归observe进行对深层对象的绑定。则asRootData为非true*/observe(data,true/* asRootData */)}
exportfunctionmountComponent(vm: Component,el: ?Element,hydrating?: boolean): Component{vm.$el=el// 如果没有!vm.$options.render方法,就创建一个空的VNODE,不是生产环境啥的报错if(!vm.$options.render){vm.$options.render=createEmptyVNode// 报错的代码}// 调用一下回调函数callHook(vm,'beforeMount')// 定义一个updateComponent方法letupdateComponent// 如果啥啥啥条件,那么updateComponent定义成如下方式,否则直接调用_update方法if(process.env.NODE_ENV!=='production'&&config.performance&&mark){updateComponent=()=>{constname=vm._nameconstid=vm._uidconststartTag=`vue-perf-start:${id}`constendTag=`vue-perf-end:${id}`// 在这里的核心调用来一下_render方法创建来一个vnodeconstvnode=vm._render()vm._update(vnode,hydrating)}}else{// 这里是定义的updateComponent是直接调用_update方法updateComponent=()=>{vm._update(vm._render(),hydrating)}}// we set this to vm._watcher inside the watcher's constructor// since the watcher's initial patch may call $forceUpdate (e.g. inside child// component's mounted hook), which relies on vm._watcher being already defined// 实例化一个渲染watcher,用处是初始化的时候会执行回调函数,// 另一个是当 vm 实例中的监测的数据发生变化的时候执行回调函数newWatcher(vm,updateComponent,noop,{before(){if(vm._isMounted){callHook(vm,'beforeUpdate')}}},true/* isRenderWatcher */)hydrating=false// 函数最后判断为根节点的时候设置 vm._isMounted 为 true, 表示这个实例已经挂载了,// 同时执行 mounted 钩子函数if(vm.$vnode==null){vm._isMounted=truecallHook(vm,'mounted')}returnvm}
Vue响应式原理
Vue是数据驱动视图实现双向绑定的一种前端框架,采用的是非入侵性的响应式系统,不需要采用新的语法(扩展语法或者新的数据结构)实现对象(model)和视图(view)的自动更新,数据层(Model)仅仅是普通的Javascript对象,当Modle更新后view层自动完成更新,同理view层修改会导致model层数据更新。
双向绑定实现机制
Vue的双向绑定实现机制核心:
Object.defineProperty()
实现数据劫持Object.defineProperty()
我们使用Object.defineProperty()进行简单的数据劫持操作:
这只是对于一个属性的设置,当我们需要劫持对象的所有的属性的时候,可以封装 Object.defineProperty()方法并借用Object.keys()进行对象可枚举属性的遍历:
通过简单的例子我们可以了解Object.defineProperty()的基本数据劫持操作,这也是Vue的响应式实现的基本原理,Vue在初始化对象的之前将数据定义在data对象中,初始化实例时对属性执行 getter/setter 转化过程,所以只有定义在data对象上的属性才能被劫持(被转化),同时因为JavaScript的限制Vue不能检测对象属性的添加和删除。
Vue源码分析
我们可以了解initState(vm)方法用来初始化Vue我们配置的方法,数据等状态,所以我们重点研究一下initState()方法:
在初始化数据的时候,我们需要判断data中的key 不能与props定义过的key重复,如果冲突将会以props定义的key优先,并且告警提示冲突。
订阅发布
Vue对象init后会进入mount阶段,执行mountComponent函数:
在mountComponent函数内部,通过new Wather()创建监听器 ,Vue Component都会经过一次mount阶段并创建一个Wather与之对应。
Wather的构造函数
new Watcher(vm, updateComponent)
:总结
参考
The text was updated successfully, but these errors were encountered: