成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【Vue原理】VModel - 源碼版 之 select 詳解

lsxiao / 441人閱讀

摘要:寫文章不容易,點(diǎn)個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理源碼版之詳解今天我們來看看處

寫文章不容易,點(diǎn)個贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】

如果你覺得排版難看,請點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧

【Vue原理】VModel - 源碼版 之 select 詳解

今天我們來看看 v-model 處理 select 有什么特殊的地方

前面已經(jīng)有三篇說明VModel了

【Vue原理】VModel - 白話版

【Vue原理】VModel - 源碼版 之 表單元素綁定流程

【Vue原理】VModel - 源碼版之input詳解

通過第一篇源碼分享,我們就知道 Vue是通過 設(shè)置 select 的 selectedIndex 來控制選項(xiàng)的,

哈哈,現(xiàn)在我們就是來分析到底是怎么設(shè)置 selectedIndex 的

好的,我們一定要帶著問題進(jìn)行學(xué)習(xí),這樣學(xué)完才有用

1、Vue 如何設(shè)置 selectedIndex

2、Vue 在哪里設(shè)置 selectedIndex
Vue 如何設(shè)置 selectedIndex

Vue 是通過 一個 setSelected 的方法專門來設(shè)置 selectedIndex 的,我們來看下源碼

function setSelected(el, binding, vm) {   

    var selected, option;   
 
    for (var i = 0, l = el.options.length; i < l; i++) {
        option = el.options[i];   
        if (isMultiple) {
            selected = value.indexOf(option) > -1;  
            if (option.selected !== selected) {
                option.selected = selected;
            }
        } 

        else {            
            if (option.value == value) {                
                if (el.selectedIndex !== i) {
                    el.selectedIndex = i;
                }               
                return
            }
        }
    } 
   
    if (!isMultiple) {
        el.selectedIndex = -1;
    }

}

兩處會修改 selectedIndex 的地方我已經(jīng)加紅加粗

簡單解釋下 setSelected 的作用

1、綁定值無法匹配任何option 時,設(shè)置 selectedIndex =-1,然后select 就會顯示空

舉栗子

select 的 selectedIndex 是-1,然后選擇框內(nèi)顯示空

2、選擇時,如果多個options 值相等時,只取第一個相等項(xiàng)

舉栗子
三個選項(xiàng)的 value 都一樣

哈哈,我明明選了3,但是 顯示1,這就是 Vue 做的處理,多個相同值的選擇,只去第一個

但是這個也是有條件的,必須在 value 變化的時候,才會進(jìn)行更新,于是才會有 判斷操作

比如現(xiàn)在select 的value是 1,你再選擇一個 也是 1 的其他選項(xiàng),Vue 就不會更新,也就不會判斷,你選了就選了,不管你了

看圖,初始化 select value 為空,然后選擇 value 是1 的 第三個選項(xiàng),

哦豁,突然變成第一個選項(xiàng)了

而我再選擇 3 和 2 的時候,卻不會變成 第一個選項(xiàng),因此 3 和2 的 value 都是 1,value 沒有變化,select 不會更新

3、選擇后,options 變化,會根據(jù)之前的選擇,更新它在options的位置

options 改變了,然后把 1 的位置變成最后一個,然后 Vue 就會相應(yīng)地把 selectedIndex 的位置更新為 新options 中對應(yīng)的位置

在哪里設(shè)置 selectedIndex

Vue 會在 v-model 的兩個鉤子函數(shù)中更新 select 的 selectedIndex

inserted

當(dāng)dom被插入到頁面中后,會觸發(fā)這個鉤子函數(shù)

上一篇詳解input我們已經(jīng)能知道,inserted 會處理select

看下 inserted 源碼(只有select 處理部分)

function inserted(el, binding, vnode, oldVnode) {    

    if (vnode.tag === "select") {

        // 設(shè)置 select 的selectedIndex 初始值
        setSelected(el, binding, vnode.context);

        // 把options 的value,全都保存到一個數(shù)組
        el._vOptions = 
            [].map
            .call(el.options, function(o){
                return o.value
            });
    }
}

componentUpdated

當(dāng)組件更新完畢之后,觸發(fā) 這個鉤子

這個鉤子函數(shù)只針對 select 處理

上 componentUpdated 鉤子函數(shù)源碼

function componentUpdated(el, binding, vnode) {    

    if (vnode.tag === "select") {

        setSelected(el, binding, vnode.context);     

        // 這是之前保存的 舊 的 options 的 所有 value 的數(shù)組 比如[ 1,2,3]
        var prevOptions = el._vOptions;   

        // 拿到 現(xiàn)在所有 option 的value 存到數(shù)組
        var curOptions = el._vOptions = [].map.call(el.options, getValue);   

        // 當(dāng) options 變化,而且跟舊option 每個都不一樣
        if (curOptions.some(function(o, i) {            
            return ! (o==prevOptions[i])
        })) {  

            var needReset = el.multiple ? 

            binding.value.some(function(v) {       
                 return hasNoMatchingOption(v, curOptions);
            }) :   

            // 綁定值變化了,而且綁定值 匹配不到 options
            // hasNoMatchingOption 是匹配 某個值是否在數(shù)組中 
            binding.value !== binding.oldValue 
            && hasNoMatchingOption(binding.value, curOptions);  

            if (needReset) {
                trigger(el, "change");
            }
        }
    }

看源碼,這個鉤子大概做了兩件事

1、立即更新 selectedIndex

為什么要立即更新,怕 options 改變了,而 select.selectedIndex 沒有變,導(dǎo)致對應(yīng)上了 新options 的 index 項(xiàng),上錯花轎嫁對郎

[ 1,2,3 ] 選擇了第3項(xiàng), 然后 index=2,值是3

然后 options 數(shù)據(jù)改變了,變成了 [7,8,9],而 index 還是2,而顯示值 變成了 9

很明顯這不符合邏輯啊,必須每次組件更新都要更新selectedIndex

2、更新綁定值

上面 componentUpdated 可以看到會手動觸發(fā) change 回調(diào)

觸發(fā)的條件是

1、options 改變,而且跟舊options每個都不一樣

2、綁定值也改變

3、新綁定值無法在 新options 中匹配對應(yīng)值

我也不懂為什么要調(diào)用一次 select 的 change 回調(diào)

要不我們 一起來查一下這個原由吧

首先,change 回調(diào),作用是更新綁定值,難道就是為了更新?

我們寫個例子看一下

兩秒之后,會把 綁定值 和 options 同時改變,而且name并不存在arr 中

既然 一開始認(rèn)為作用更新 綁定值,那我們看下綁定值更新成了什么鬼

變成了 undefined

的確是更新了綁定值哦,可是為什么要更新綁定值為 undefined 呢?想不通.....

上面是從內(nèi)部去修改 綁定值的,我們從外部修改看一下,把內(nèi)部修改的語句注釋掉

發(fā)現(xiàn) 外部修改綁定值,再改變 options ,外部修改的綁定值是不會隨著options變化而更新的哦

話說其實(shí)這里我沒太想通,也不知道自己想得對不對,感覺這里可以討論一下

根據(jù)上面的現(xiàn)象,我說出我的想法

我覺得尤大的想法是,從用戶角度出發(fā)

如果用戶沒有選擇任何option

但是 options 和 綁定值 同時改變,而且綁定值還不匹配options

這個綁定值改變有個毛用?。???

作為表單數(shù)據(jù),你自己內(nèi)部修改綁定值還不匹配任何option

這樣,用戶根本不知道你修改,他壓根沒選擇,而提交的時候,提交卻有數(shù)據(jù),這是干毛?

舉栗子

選擇最愛的水果,options = [ 西瓜,香蕉,番茄 ]

你修改成了 options = [ 橙子,蘋果,雪梨 ],還把用戶的選擇值改成 錘子

用戶還不知道你修改了,我喜歡個錘子喜歡

沒道理啊是不是,所以最好是 重置為 undefined

也剛好符合 源碼的語義 needReset

額,我是這么想的,也不知道對不對,勿噴我,不過我覺得我的想法很有道理啊

如果用戶已經(jīng)選擇option

就算options 改變了,那本質(zhì)上也是沒有錯的,因?yàn)槭怯脩糇约哼x擇,就算不匹配新options,所以就沒必要重置了

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105201.html

相關(guān)文章

  • Vue原理VModel - 源碼 表單元素綁定流程

    摘要:首先,兄弟,容我先說幾句涉及源碼很多,篇幅很長,我都已經(jīng)分了上下三篇了,依然這么長,但是其實(shí)內(nèi)容都差不多一樣,但是我還是毫無保留地給你了。 寫文章不容易,點(diǎn)個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也...

    sarva 評論0 收藏0
  • Vue原理VModel - 源碼input詳解

    摘要:因?yàn)槭ソ裹c(diǎn)之后被強(qiáng)制更新了一波嗯,這就是的作用,把頁面上的顯示值也過濾一遍 寫文章不容易,點(diǎn)個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】VModel - 源碼版之input詳...

    leanxi 評論0 收藏0
  • Vue原理VModel - 白話

    摘要:執(zhí)行的時候,會綁定上下文對象為組件實(shí)例于是中的就能取到組件實(shí)例本身,的代碼塊頂層作用域就綁定為了組件實(shí)例于是內(nèi)部變量的訪問,就會首先訪問到組件實(shí)例上。其中的獲取,就會先從組件實(shí)例上獲取,相當(dāng)于。 寫文章不容易,點(diǎn)個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得...

    keke 評論0 收藏0
  • Vue原理】Compile - 源碼 generate 節(jié)點(diǎn)數(shù)據(jù)拼接

    摘要:寫文章不容易,點(diǎn)個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理源碼版之節(jié)點(diǎn)數(shù)據(jù)拼接上一篇我們 寫文章不容易,點(diǎn)個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究...

    fizz 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<