国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

lsxiao / 443人閱讀

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

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

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

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

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

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

【Vue原理】VModel - 白話版

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

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

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

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

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

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

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

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

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;
    }

}

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

簡(jiǎn)單解釋下 setSelected 的作用

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

舉栗子

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

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

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

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

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

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

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

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

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

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

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

在哪里設(shè)置 selectedIndex

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

inserted

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

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

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

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

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

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

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

componentUpdated

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

這個(gè)鉤子函數(shù)只針對(duì) 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 每個(gè)都不一樣
        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 是匹配 某個(gè)值是否在數(shù)組中 
            binding.value !== binding.oldValue 
            && hasNoMatchingOption(binding.value, curOptions);  

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

看源碼,這個(gè)鉤子大概做了兩件事

1、立即更新 selectedIndex

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

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

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

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

2、更新綁定值

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

觸發(fā)的條件是

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

2、綁定值也改變

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

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

要不我們 一起來(lái)查一下這個(gè)原由吧

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

我們寫個(gè)例子看一下

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

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

變成了 undefined

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

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

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

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

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

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

如果用戶沒(méi)有選擇任何option

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

這個(gè)綁定值改變有個(gè)毛用啊???

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

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

舉栗子

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

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

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

沒(méi)道理啊是不是,所以最好是 重置為 undefined

也剛好符合 源碼的語(yǔ)義 needReset

額,我是這么想的,也不知道對(duì)不對(duì),勿噴我,不過(guò)我覺(jué)得我的想法很有道理啊

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/105201.html

相關(guān)文章

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

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

    sarva 評(píng)論0 收藏0
  • Vue原理VModel - 源碼input詳解

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

    leanxi 評(píng)論0 收藏0
  • Vue原理VModel - 白話

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

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

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

    fizz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<