为什么给select下的options设置字体无效_【Vue原理】VModel - 源码版 之 select 详解...

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

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

【Vue原理】VModel - 源码版 之 select 详解​mp.weixin.qq.com
29a4d47efffc61eca445e9b0dd34b64a.png

c7c9ffeefc098e0a6616ad9515a0c08d.png

额,昨天发现发的文章图片全都不见了,所以删了重新今天发一遍了...真的坑

今天我们来看看 v-model 处理 select 有什么特殊的地方

前面已经有三篇说明VModel了

【Vue原理】VModel - 白话版

【Vue原理】VModel - 源码版 之 表单元素绑定流程

【Vue原理】VModel - 源码版之input详解

通过第一篇源码分享,我们就知道 Vue是通过 设置 select 的 selectedIndex 来控制选项的,

哈哈,现在我们就是来分析到底是怎么设置 selectedIndex 的

好的,我们一定要带着问题进行学习,这样学完才有用

1、Vue 如何设置 selectedIndex

2、Vue 在哪里设置 selectedIndex

969c3cf6c42a00325c5af4298e0465ad.png

Vue 如何设置 selectedIndex

Vue 是通过 一个 setSelected 的方法专门来设置 selectedIndex 的,我们来看下源码

function 

两处会修改 selectedIndex 的地方我已经加红加粗

简单解释下 setSelected 的作用

1、绑定值无法匹配任何option 时,设置 selectedIndex =-1,然后select 就会显示空

举栗子

c6736f9e31a4020c0c34587e49f7c6c1.png

5d6822c8985d4ba3ff836f3f4c9d5f74.png

select 的 selectedIndex 是-1,然后选择框内显示空

fb3f7c6f49f40dfee5dceddfe8de0a4d.png

389eb8d1dddf61a8934b0b53f8a3d084.png

2、选择时,如果多个options 值相等时,只取第一个相等项

举栗子
三个选项的 value 都一样

1edce668bafca53d3b7489c9e8e9cc07.png

5d6822c8985d4ba3ff836f3f4c9d5f74.png

fb80e4a7d4bb498bee54c0b7202453c3.gif

哈哈,我明明选了3,但是 显示1,这就是 Vue 做的处理,多个相同值的选择,只去第一个

但是这个也是有条件的,必须在 value 变化的时候,才会进行更新,于是才会有 判断操作

比如现在select 的value是 1,你再选择一个 也是 1 的其他选项,Vue 就不会更新,也就不会判断,你选了就选了,不管你了

看图,初始化 select value 为空,然后选择 value 是1 的 第三个选项,

哦豁,突然变成第一个选项了

而我再选择 3 和 2 的时候,却不会变成 第一个选项,因此 3 和2 的 value 都是 1,value 没有变化,select 不会更新

5ea6cfb5b0661a8fa46343825c72ca90.gif

3、选择后,options 变化,会根据之前的选择,更新它在options的位置

a52069905078acb2553b46725bc7c1cb.png

ae8fae24e07b6a18a6d2da77378a7565.png

1d0df7da33fa251e710895ac1c31cf70.png

options 改变了,然后把 1 的位置变成最后一个,然后 Vue 就会相应地把 selectedIndex 的位置更新为 新options 中对应的位置

ba526a861d51c3c68a074eeb6ed749f7.gif

969c3cf6c42a00325c5af4298e0465ad.png

在哪里设置 selectedIndex

Vue 会在 v-model 的两个钩子函数中更新 select 的 selectedIndex

inserted

当dom被插入到页面中后,会触发这个钩子函数

上一篇详解input我们已经能知道,inserted 会处理select

看下 inserted 源码(只有select 处理部分)

function 

componentUpdated

当组件更新完毕之后,触发 这个钩子

这个钩子函数只针对 select 处理

上 componentUpdated 钩子函数源码

function 

看源码,这个钩子大概做了两件事

1、立即更新 selectedIndex

为什么要立即更新,怕 options 改变了,而 select.selectedIndex 没有变,导致对应上了 新options 的 index 项,上错花轿嫁对郎

[ 1,2,3 ] 选择了第3项, 然后 index=2,值是3

然后 options 数据改变了,变成了 [7,8,9],而 index 还是2,而显示值 变成了 9

很明显这不符合逻辑啊,必须每次组件更新都要更新selectedIndex

6f59b527b67fb318dd891c1285087c43.gif

2、更新绑定值

上面 componentUpdated 可以看到会手动触发 change 回调

触发的条件是

1、options 改变,而且跟旧options每个都不一样

2、绑定值也改变

3、新绑定值无法在 新options 中匹配对应值

我也不懂为什么要调用一次 select 的 change 回调

要不我们 一起来查一下这个原由吧

首先,change 回调,作用是更新绑定值,难道就是为了更新?

我们写个例子看一下

468ad7ff726f51b73c6b6b70e5f75ea5.png

3decbc38ef0221063f9b5e46a00be19f.png

两秒之后,会把 绑定值 和 options 同时改变,而且name并不存在arr 中

91243d5d5e8137e310ae8b4e33322d58.png

既然 一开始认为作用更新 绑定值,那我们看下绑定值更新成了什么鬼

06b9d1203e9973667a7ba2064ce53703.gif

变成了 undefined

的确是更新了绑定值哦,可是为什么要更新绑定值为 undefined 呢?想不通.....

上面是从内部去修改 绑定值的,我们从外部修改看一下,把内部修改的语句注释掉

f32d2ac70791d7e3fc94e11434e34285.png

3e371bcb01d2da29706c929d837a70d4.gif

发现 外部修改绑定值,再改变 options ,外部修改的绑定值是不会随着options变化而更新的哦

话说其实这里我没太想通,也不知道自己想得对不对,感觉这里可以讨论一下

根据上面的现象,我说出我的想法

我觉得尤大的想法是,从用户角度出发

如果用户没有选择任何option

但是 options 和 绑定值 同时改变,而且绑定值还不匹配options

这个绑定值改变有个毛用啊???

作为表单数据,你自己内部修改绑定值还不匹配任何option

这样,用户根本不知道你修改,他压根没选择,而提交的时候,提交却有数据,这是干毛?

举栗子

选择最爱的水果,options = [ 西瓜,香蕉,番茄 ]

你修改成了 options = [ 橙子,苹果,雪梨 ],还把用户的选择值改成 锤子

用户还不知道你修改了,我喜欢个锤子喜欢

没道理啊是不是,所以最好是 重置为 undefined

也刚好符合 源码的语义 needReset

a1e4807e2f3cbeb729fef496e5068815.png

额,我是这么想的,也不知道对不对,勿喷我,不过我觉得我的想法很有道理啊

如果用户已经选择option

就算options 改变了,那本质上也是没有错的,因为是用户自己选择,就算不匹配新options,所以就没必要重置了

969c3cf6c42a00325c5af4298e0465ad.png

历史分享

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

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

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

【Vue原理】Props - 白话版

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

【Vue原理】Watch - 白话版

【Vue原理】Mixin - 白话版

【Vue原理】Methods - 源码版

【Vue原理】VModel - 白话版

【Vue原理】VModel - 源码版 之 表单元素绑定流程

【Vue原理】VModel - 源码版之input详解

969c3cf6c42a00325c5af4298e0465ad.png

最后

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

当然如果本文有任何描述不当的问题,欢迎后台联系本人

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值