combox绑定值以后再赋值给text_【Vue原理】VModel - 源码版 之 表单元素绑定流程

0c4575d9c732cdab87aaacf8e77ce9d7.png
专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和 Vue的美,喜欢我就关注我的公众号,公众号的文章,排版更好看

如果你觉得排版难看,请点击下面链接 或者 关注公众号

【Vue原理】VModel - 源码版 之 表单元素绑定流程​mp.weixin.qq.com
9c33bf7f8dcd931c1a9e71ca6724ab3f.png

1e66c406c6921d2170fdbfef4da96599.png

今天讲解 v-model 的源码版。首先,兄弟,容我先说几句

abbfd6ab8c3501d2a371c50423b70fab.png

v-model 涉及源码很多,篇幅很长,我都已经分了上下 三篇了,依然这么长,但是其实内容都差不多一样,但是我还是毫无保留地给你了。你知道我这篇文章写了多久,一个多星期啊,不是研究多久啊,是写啊写啊,不停地修修改改,一直在想如何才能讲明白

611b9f70ff01507f6efdaec181176c0c.png

如果你做好了十足的学习准备,会对你事半功倍,如果你只是看看,请看白话版吧,不然估计会越看越烦.....

如果你看过白话版,估计你会了解今天内容的大概,也能很快就入戏

今天讲解不同表单元素的Vue是如何处理的,表单元素有

inputtextareaselectcheckboxradio 五大种

所以,我们把每个表单元素当做一个模块,然后每个模块解决三个问题的流程,来开始我们今天的表演

1、v-model 如何绑定表单值

2、v-model 如何绑定事件

4、v-model 如何双向更新

TIP

下面所有涉及到的源码,为了方便理解,都是简化过的,因为源码太长,所以只保留主要思想,去掉了很多兼容处理以及错误处理

8c66dc5fdac4c7b0c574d1ffc465ef50.png

v-model 指令的处理

我们现在假设模板的解析已经到了 解析 v-model 的部分....

Vue 会调用 model 方法 来解析 v-model ,这个方法里面,针对不同的表单元素,再调用不同的专属方法进行深度解析

function 

你也看到了,上面每种表单元素都会使用一个方法来特殊照顾,不过这些方法,作用大致一样

1、给表单元素设置绑定值

2、给表单元素设置事件及回调

所以这里,我们把方法的都设计到的方法以及流程说一下

插播上面的el 是什么?

el 是 ast,而我的理解就是解析模板后,用树结构来表示某个dom节点,这里先不用深究,你就只要知道他是保存解析模板后所有的数据,包括你绑定的事件,绑定的指令,绑定的属性等等,一张图看下

e5814ca7d96f2da107b9bcec7753735e.png

下面所有的处理都是以 el 为基础的

表单元素设置绑定值

什么叫设置绑定值?

首先,比如你给表单元素设置 v-model ="name",name 是 内部数据吧,所以要把 name 和 表单元素 两个紧紧绑定起来,方便后面进行双向更新

这里讲的是每个表单元素绑定值的流程

他们都会调用 addProp 去保存绑定的属性 然后 绑定属性,流程一样,所以提出来讲,但是具体绑定什么属性,每种元素都不尽相同,在下面表单元素模块会详解

1、调用 addProp,把 value 添加进 el.props

function 

2、接下来的解析,el.props 会拼接成进字符串 domProps

function 

3、在插入 dom 之前,调用 updateDOMProps,把 上面保存的 domProps 遍历赋值到 dom 上

function 

表单元素设置事件以及回调

这里讲的是每个表单元素绑定事件的流程

1、拼接事件

每种元素拼接事件都不一样,在下面表单元素模块会详解

2、保存事件名和拼接好的回调

每个元素的 event 事件 和 拼接的回调是不一样,但是他们保存的流程都是一样的,都会调用下面的方法,addHandler 去保存事件

下面 el 是dom 元素,event 是事件名,code 是拼接的回调

0d9f37618578a6533b0b428a49bbbd40.png
function 

3、完善拼接回调

function 

genHandlers遍历 el.event ,每一项的回调最外层包上一层 function 字符串,并把 所有事件 逐个拼接成 on 字符串

function 

转接的 初始数据和结果 像下面这样

01d2344ebd1f748bc0c18475b24ee764.png

4、绑定事件

在插入 dom 之前

会调用到 updateDOMListeners,把 上面保存到 on 的 所有事件, 遍历绑定到 dom 上

updateDOMListeners 其实兜兜转转了很多方法 来处理,为了方便理解,已经非常简化,但是意思是不变的

尤大:卧槽,我写几百行,你浓缩成5行,你这是要向全国人民谢罪的啊

05b43725dc61ac0e6c36f8c11a37764f.png
function 

下面所有例子使用这个vue实例,所有绑定 v-model 我都用 name

aec8638dd45cd6eb6c7354ce83b98c45.png

8c66dc5fdac4c7b0c574d1ffc465ef50.png

Input、Textarea

哟哟,看过 model ,就知道 这两种元素是使用 genDefaultModel 处理的

function 

绑定值

看了上面的函数,你就知道啦,input 和 textarea 调用 addProp 绑定的是 value

拼接事件

其实这里精炼就一句话,比 jio 简单

name = $event.target.value

但是呢!input 这里其实是很复杂的,比如兼容 range 啦,预输入延迟更新啦 等等,但是现在我们不说这些,放到下篇来讲

然后,你能看到,input 和 textarea 一般绑定的是 input 事件,但是也有其他的处理,下篇讲啦

编译后的渲染 render 函数

6136eb6474de8438ddcf8dfc45ba7318.png
with

双向更新

我们可以看到上面的 render 执行的时候,从实例读取了 name,name 收集到 本组件 watcher

1、内部变化,通知更新 watcher,render 重新执行,获取新的 name,绑定到 dom 元素属性 value

2、外部变化,看上面的回调事件,可以知道直接把 $event.target.value 赋值给 内部值name

8c66dc5fdac4c7b0c574d1ffc465ef50.png

Select

来看看 处理 select 的 genSelect 方法

function 

绑定值

select 元素绑定的属性是 selectedIndex,但是 select 并没有在 genSelect 方法中调用addProp 绑定某个属性

那么 select 在哪里设置了呢?Vue 专门使用了方法 setSelected 设置 selectedIndex,这个方法现在不说,你只要知道,他是更新 selectedIndex 的就好了,后面会有一篇专门说

疑惑为什么 select 不像 input 一样直接绑定 value,这样,不是也可以确定选项吗?

按我的理解呢,我觉得应该是原始select的 value 只有字符串一类型的值,而 Vue 的select 支持 数字和字符串两种类型的值啊

拼接事件

观察下面的渲染函数,就可以很清楚地名表,select 的回调是怎么一回事了

1、从所有option 中 筛选出被选择的option

2、使用数组保存所有筛选后的option的value

3、判断是否多选,多选返回数组,单选返回数组第一项

然后,你还能知道 select 绑定的是 change 事件

献上 select 的渲染 render 函数

99f84879fd06876276659fdcbf44c666.png
with

双向更新

render 执行时,directive 处从实例读取了 name, name 收集到 本组件 watcher

1、内部变化,通知更新 watcher,上面 render 重新执行,获取新name,于是更新 select 元素属性 selectedIndex,于是select 当前选项就改变了

2、外部变化,直接赋值给 绑定值,绑定值变化,通知 watcher 更新,更新完,重新设置 selectedIndex

8c66dc5fdac4c7b0c574d1ffc465ef50.png

Checkbox

genCheckboxModel 源码奉上

function 

绑定值

赋值给 checked

看上面的方法就知道啦,调用 addProps,设置 checked 值

拼接事件

哈哈,还是看下面的渲染函数,看下 checkbox 的回调,其实意思就是

1、数组,分是否选择

a. 选择,把当前选项 concat 进数组

b. 取消选择,把当前选项 移除出数组

2、非数组,直接赋值

你还能知道 checkbox 绑定的是 change 事件

来看看checkbox 的渲染render函数

2478a847808224d34c1e817c7437121a.png
with

双向更新

在 render 执行的时候,从实例读取了 name,name 收集到 本组件的 watcher

1、内部变化,通知更新 watcher,上面的 render 重新执行,获取新的 name,更新 checkbox 元素属性 checked

2、外部变化,判断是否多选和是否选择,来决定如何赋值 更新 绑定值 name

8c66dc5fdac4c7b0c574d1ffc465ef50.png

Radio

处理 radio 元素的 genRadioModel 源码

function 

怎么赋值

直接赋值给 checked,你看上面的方法调用 addProp 可以看到

拼接事件

这个真的更加简单了...比 input 还简单啊,都不用获取值,只是直接赋值为 radio 的值

name="1", 1 是你设置给 radio 的value值

你还能知道 radio 绑定的是 change 事件

看下下面的radio 的渲染函数你就懂了

82ecf7b35ce4339580f29789e5121177.png
with

双向更新

在 render 执行的时候,绑定值 收集到 本组件的 watcher

1、内部变化,通知更新 watcher,render 重新执行,获取新的 name,更新 radio 元素属性 checked

2、外部变化,直接赋值 更新 绑定值 name 等于 radio元素属性 value

8c66dc5fdac4c7b0c574d1ffc465ef50.png

历史分享

【Vue原理】Vue源码阅读总结大会 - 序

【Vue原理】学会调试Vue源码

【Vue原理】响应式原理 - 白话版

【Vue原理】Props - 白话版

【Vue原理】月老Computed - 白话版

【Vue原理】Watch - 白话版

【Vue原理】Mixin - 白话版

【Vue原理】Methods - 源码版

8c66dc5fdac4c7b0c574d1ffc465ef50.png

最后

希望你认真阅读后,能豁然开朗。如果你懂了,我的目的也达到了,如果你还不懂,可以留言告诉我哦,百分百回复好吧

如果你能转发一下,就更好啦,技术人交流 只用文章

1e66c406c6921d2170fdbfef4da96599.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值