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
functionupdateDOMProps(oldVnode,vnode){if(isUndef(oldVnode.data.domProps)&&isUndef(vnode.data.domProps)){return}varkey,cur;varelm=vnode.elm;varoldProps=oldVnode.data.domProps||{};varprops=vnode.data.domProps||{};// clone observed objects, as the user probably wants to mutate itif(isDef(props.__ob__)){props=vnode.data.domProps=extend({},props);}for(keyinoldProps){if(isUndef(props[key])){elm[key]='';}}for(keyinprops){cur=props[key];
...
// 如果是input的value属性if(key==='value'){// store value as _value as well since// non-string values will be stringifiedelm._value=cur;// avoid resetting cursor position when value is the samevarstrCur=isUndef(cur) ? '' : String(cur);if(shouldUpdateValue(elm,strCur)){// 更新dom对应的value值elm.value=strCur;}}else{elm[key]=cur;}}}
v-model的实现
v-model
是Vue
内部实现的一个指令。它所提供的基本功能是在一些表单元素上实现数据的双向绑定。基本的使用方法就是:页面初次渲染完成后,
input
输入框的值为default val
,当你改变input
输入框的值的时候,你会发现控制台也打印出了输入框当中新的值。接下来我们就来看下v-model
是如何完成数据的双向绑定的。首先第一步,在这个
vue
实例化开始后,首先将data
属性数据变成响应式的数据。接下来完成页面的渲染工作的时候,首先编译html
模板:接下来我们深入细节的看下整个绑定的过程,以及在页面当中修改
input
输入框中的值后,如何使得模型数据也发生变化。示例当中是在
input
元素上绑定的v-model
指令,它是属于built in elements
,因此不同于自定义component
创建VNode
过程中还需要进行获取props
属性,自定义事件,初始化钩子函数等,而attrs
,domProps
,on
属性最终都会绑定到dom
元素上。当调用
_c
方法完成后,即VNode
都已经生成完毕,开始将VNode
渲染成真实的dom
节点并挂载到document
中去:在页面初始化的阶段:
// TODO: 递归如何描述
在渲染
VNode
过程当中,如果是自定义的component VNode
,那么首先完成component
的vm
实例化,接下来递归的对子节点进行实例化注意当子 VNode 全部渲染成真实的 dom 节点,并挂载到父节点后,开始调用
invokeCreateHooks
方法,触发dom
节点create
阶段所包含的钩子函数来完成对dom
节点添加attrs
,domProps
,dom事件
等:(具体的可参见 createPatchFunction 方法中对于 create 阶段所有的回调函数的初始化)在这里我们只关心和
v-model
相关的domProps
和dom事件
的钩子函数,首先来看下更新domProps
的钩子函数:在
dom
初次创建的过程中,通过updateDOMProps
方法完成dom
的value
的初始化。接下来看下是如何绑定
dom
事件的:在本例当中,即向
input
节点绑定input
事件:当改变
input
输入框的内容时,触发input
事件执行对应的回调函数,这个时候便会改变响应式数据val
的值,即调用val
的setter
方法。因为之前在创建 input 的 VNode 的时候,val 收集到了这个 VNode 对应的 render watcher。所以当 val 的 setter 被触发的时候,会让 input 对应的 render watcher 重新执行,这样也就会触发这个 dom 节点的 diff 和渲染的工作。// 创建
VNode
环节// 渲染的环节
// 绑定dom
// TODO: 总体的的概述
// 如何绑定/更新domProps
// 绑定原生的dom事件
// 和dom相关的attrs、domProps、原生的dom事件、style等,都是在将vnode渲染成真实的dom元素后,并关在到父dom节点后完成的。
The text was updated successfully, but these errors were encountered: