v-model
v-model

应用在特定的表单元素标签上会绑定不同的指令对象,具体是
input
vModelSelect。
vModelTextvModelText
如果当前节点是正在被操作也就是获得了焦点就进行相关操作,主要是如果新旧值如果一样则不进行更新操作以节省性能开销
===
生命周期函数之前会构造指令生命周期函数所需的参数并传递过来。
按照顺序分别对应第一个参数是当前节点的真实
DOM
函数中封装的包含指令对象相关的参数,比如指令的参数,指令的修饰符等等,第三个则是当前节点的虚拟
DOM。
这样我们就可以在指令的生命周期函数里面获取到当前节点的相关信息了。
createdcreated
getModelAssigner(vnode)一行代码,这一行代码主要是获取当前节点
props
中的v-model绑定的状态更新函数,我们回顾上文,每一个应用了v-model的元素标签,编译成
render
函数之后都会有一个"onUpdate:modelValue":
$event
props,这个就是当前节点v-model绑定的状态更新函数。
constgetModelAssigner
vnode.props!['onUpdate:modelValue']
return
}
有可能存在多个状态更新函数,如果是多个状态更新函数则则封装一个高级函数进行调用处理。
在
Vue
修饰符有以下的介绍:
在默认情况下,
v-model在input事件中同步输入框的值与数据IME
部分),但你可以添加一个修饰符
lazy,从而转变为在change事件中同步。
我们通过观察源码可以更深刻理解
lazy
事件是实时触发的,就是当输入框里的值发生改变就会立即触发,而
change
事件则需要等到失去焦点才触发。
在监听的回调函数中最终目的就是为了去更新v-model绑定的状态数据,简单来说就是通过当前真实节点的引用也就是
value
中的onUpdate:modelValue状态更新函数来进行更新应用状态。
这就是用户操作
DOM
到数据的变化过程原理。
此外在更新之前会对当前节点的真实
DOM
的值也就是el.value,进行判断处理作对应的处理。
比如,如果存在
trim
修饰符的时候,也就是需要实时监听输入的时候,需要利用
compositionstart
监听控制中文输入的开始和结束动作。
因为默认输入框并不知道中文输入法的开始和结束
具体的做法就是在
compositionstart
函数是在绑定元素的被挂载到父节点后通过异步调用执行的,主要是因为组件本身的生命周期函数
onMounted
函数也需要异步进行执行,这样才能确保所有的节点都已经被挂载完毕,指令做所用的状态数据是最新的。
vModelText
指令中
函数所做的事情很简单,就是把v-model绑定的状态数据赋值给绑定的表单元素。
我们从前面对
withDirectives
属性就是v-model所绑定的状态数据。
这个也就是初始化的时候v-model绑定的数据是怎么被赋值到所绑定的表单元素上的原理。
beforeUpdate
函数
如果我们在程序里面更改了v-model所绑定的状态数据,那么最新的状态数据就是通过指令的
beforeUpdate
生命周期函数更新到所绑定的元素上的。
具体是因为v-model所绑定的状态数据是响应式的,所以其发生了变化就会引起组件的重新渲染。
通过上文我们知道元素的更新是通过
patchElement
上之前会做一系列的性能优化操作,主要是如果状态数据和真实
DOM
指令的基础,后面的我们就不进行十分详细的分析了,只做简单的分析。
vModelRadio
指令源码如下:
exportconst
函数之前,我们先回顾一下单项选择框的使用:
<inputv-model="state">
我们先会给单项选择表单设置一个
value
的值的时候,单项选择框处于选中状态,也就是
checked
true。
所以在初始化的时候,首先是通过
looseEqual
value,从前文我们可以知道是v-model绑定的值,也就是上面的
state,而
属性上,从而单项选择框处于选中状态。
单项选择只需要监听
change
更新函数进行更新状态值,也就是用户点击选项选择表单之后,从真实
DOM
的变化到数据变化的流程。
这里有一个点需要值得说明的是
getValue
中是否存在_value属性,如果存在就获取_value属性值,否则就获取
value
值。
这是为什么呢?我们来看看下面的代码:
//packages\runtime-dom\src\modules\props.ts
export
值时会被设置到一个自定义属性_value上,此外还有
select
值也是同样的处理。
此外,
当我们在普通文本输入框进行以上操作时:
<inputv-model="state">
这个时候编译器会报错:
内部服务器错误:在使用
v-model
函数
从前文我们可以知道如果我们在程序里面更改了v-model所绑定的状态数据,那么最新的状态数据就是通过指令的
beforeUpdate
生命周期函数更新到所绑定的元素上的。
vModelRadio
beforeUpdate
函数的实现很简单,通过前文的学习我们可以很容易看懂,没有太多好说的。
vModelCheckboxtrue-value
/>
true-value和false-value是
Vue
attributes,仅支持和v-model配套使用。
这里toggle属性的值会在选中时被设为'yes',取消选择时设为'no'。
上述例子来自
Vue
官网,更多详细请查看官网例子。
此外还有将多个复选框绑定到同一个数组或集合的值:
<inputv-model="checkedNames">
<input
v-model="checkedNames">
<input
v-model="checkedNames">
如果选中了,复选框表单中设置的值就会添加到状态变量
checkedNames
数组中存在哪些元素值,那么哪些复选框则是选中状态。
还有单一的复选框,绑定布尔类型值:
<input/>
如果选中,状态变量
checked
的布尔绑定值”,所以我们需要先了解这些前置知识。
vModelCheckboxvModelCheckbox
指令的源码:
exportconst
assign(modelValue.concat(elementValue))
else
}
由于复选框的使用方式不同,所以
vModelCheckbox
事件的回调函数中使用v-model绑定的状态数据,如果是通过
created
生命周期中参数中获取v-model绑定的状态数据,则会是一个闭包变量,且每次重新渲染更新生产的
vnode
都会重新创建新的v-model绑定的状态数据,所以通过
created
生命周期中参数中获取v-model绑定的状态数据将不会是最新的数据,所以需要把v-model绑定的状态数据设置到一个全局变量中去。
vModelCheckbox
钩子函数中把v-model绑定的状态数据设置到节点元素
DOM
事件的回调函数中,获取v-model绑定的状态数据也就是
DOM
的数据类型进行不同的处理。
modelValuemodelValue
数组中。
如果不存在且当前复选框是选中状态则需要把当前复选框的选项值添加到
modelValue
数组中,然后通过更新函数更新v-model中绑定的状态数据。
如果当前选项存在
modelValue
数组中删除,然后通过更新函数更新v-model中绑定的状态数据。
modelValueSet
由于
的情况处理起来比数据类型是数组的情况要简单很多,也就是如果复选框是选中状态则把复选框的选项值添加到
modelValue
中删除,然后通过更新函数更新v-model中绑定的状态数据。
如果是单一的复选框
modelValue
Set
函数中进行处理了。
getCheckboxValue
函数源码:
functiongetCheckboxValue(el,
}
首先根据复选框的选中状态是判断是获取_trueValue还是_falseValue作为
key,然后判断复选框
上有没有存在这两个属性,如果存在就返回这两个属性对应的属性值,否则返回当前复选框的选中状态。
值得注意的是当我们使用使用
true-value
属性设置成_trueValue还是_falseValue挂在元素实例对象上。
以下是
Vue3
packages\runtime-dom\src\patchProp.ts
export
}
以上就是用户点击复选框之后,从真实
DOM
设置完毕。
我们可以回顾一下前面的指令的执行流程中的知识。
created
DOM
实例之后,并且通过异步执行确保所有的应用节点都挂载完成后执行的,所以在
mounted
的_modelValue属性上,以供在
created
函数是实现过程是一致的,所以通过封装共同的函数达到共享逻辑的目的。
以下是
setChecked
函数的源码:
functionsetChecked(el,
}
具体是根据v-model中绑定的状态数据
value
函数一致,这里就不再进行赘述了。
至此


