前端小夥伴們有沒有遇到過這樣的場景,iviewUI組件庫中select雙向綁定數據時,修改了綁定值,可是頁面中渲染的值仍是以前的值,不論是去打印仍是使用vue插件去查看變量,均顯示綁定值已修改,但是頁面始終顯示修改以前的數據,是否是很困惱,心中簡直是臥槽、臥槽、臥槽。html
我以前作過很暴力的事情,就是在select標籤上綁定v-if,在修改v-modal的值時,對v-if對應的變量先賦值false,緊接着賦值true,若是還不行就加個延時settimeout。當時還爲本身的機智洋洋得意,如今想一想屬實是真沒文化,吃了讀書少的虧。前端
最近從新閱讀vue官網文檔時,讀到了這段話:vue
當 Vue.js 用 v-for
正在更新已渲染過的元素列表時,它默認用 「就地複用」 策略。若是數據項的順序被改變,而不是移動 DOM 元素來匹配數據項的順序, Vue 將簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。這個相似 Vue 1.x 的 track-by="$index"
。react
這個默認的模式是有效的,可是隻適用於不依賴子組件狀態或臨時 DOM 狀態(例如:表單輸入值)的列表渲染輸出。算法
爲了給 Vue 一個提示,以便它能跟蹤每一個節點的身份,從而重用和從新排序現有元素,你須要爲每項提供一個惟一 key
屬性。理想的 key
值是每項都有惟一 id。這個特殊的屬性至關於 Vue 1.x 的 track-by
,但它的工做方式相似於一個屬性,因此你須要用 v-bind
來綁定動態值(在這裏使用簡寫):bash
<div v-for="item in items" :key="item.id"> <!-- 內容 --></div>複製代碼 |
建議儘量使用 v-for
來提供 key
,除非迭代 DOM 內容足夠簡單,或者你是故意要依賴於默認行爲來得到性能提高。iview
由於它是 Vue 識別節點的一個通用機制, key
並不特別與 v-for
關聯,key 還具備其餘用途,咱們將在後面的指南中看到其餘用途。dom
劃重點了,劃重點了,劃重點了,重要的事說三遍,ide
由於它是 Vue 識別節點的一個通用機制, key
並不特別與 v-for
關聯,key 還具備其餘用途,咱們將在後面的指南中看到其餘用途。
性能
由於它是 Vue 識別節點的一個通用機制, key
並不特別與 v-for
關聯,key 還具備其餘用途,咱們將在後面的指南中看到其餘用途。
由於它是 Vue 識別節點的一個通用機制, key
並不特別與 v-for
關聯,key 還具備其餘用途,咱們將在後面的指南中看到其餘用途。
我覺着key能夠爲我作點什麼,以後我又看了一下react中diff算法的文章(vue原理與之一致),發現這個key果然厲害的不要不要的。
key值的做用主要用來減小不必的diff算法的對比,對於同一個組件或者節點來講,只要父節點狀態或屬性發生改變,該組件就會進行diff 對比,即便該組件沒有發生改變;若是爲該組件引入key值,在進行diff對比前先作一次校驗,判斷該組件是否須要diff對比,也能夠判斷該 組件是直接更新操做仍是銷燬或者新建操做,從而提升了diff算法的效率;特別在渲染同級同結構的組件們時,key能夠爲它們加上了身份的 標誌,在rerender時,能夠經過key來判斷該組件是否已經存在,是否須要跟新或者銷燬,新建等操做,提升了diff算法在同級節點上的操做。 原理: 由於在reactelement中有一個屬性是key,該屬性默認是爲空值,因此通常狀況下,只要組件不加上key值,react是不會去校驗組件 的key,而是直接採用diff算法進行對比,一旦組件加上了key值,react就會在渲染時對該組件的身份進行校驗,首先校驗新舊組件的key值 是否是一致,不一致的話,該組件直接銷燬,而後在新建該組件;若是一致,則比較組件的屬性是否發生變化,若是發生變化,則採用diff算 法進行對比,而後得出差別對象,若是屬性沒發生變化,則認爲該組件不須要改變;
回到文章一開始提到的問題,個人理解是select這部分的dom被就近複用了,所以有時纔會出現修改v-modal的值以後頁面顯示的是以前的值,所以,我就想到了,爲何不能在select上綁定key值,說作就作。
<select v-modal="selectValue" :key="selectkey" @onChange="selectChange">
<option>111</option>
...
</select>複製代碼
每次修改值的時候我會讓selectKey自增一下,也就是說讓select的身份標識發生變化,獲得從新渲染,這樣就規避掉綁定值不生效的現象了,也規避掉v-if帶來的閃一下的不良體驗。
親測有效,但願遇到相同問題的小夥伴可以用得上。