高產似母豬。。寫完上篇看了幾集新番就空虛了。。零點時分決定爬起來,趁着清明假期能寫多寫點。
1.前言
我們知道彈出框都是在觸發了某種條件后展示,而一個個的新的彈出框的展示,總是覆蓋着上一個彈出框。實現覆蓋功能需要保證新的彈出框的z-index要比舊的彈出框的z-index值相等或着更高,為達到這個目的element為所有的彈出框(所有下拉框、提示框、Dialog對話框等等)直接或間接的使用到一個js組件element-ui/src/utils/vue-popper
,而這個vue-popper又使用了另一個組件element-ui/src/utils/popup/popup-manager.js
。
PopupManager
PopupManager中有一個zIndex屬性初始值為2000,所有的彈出框的z-index其實都是從這個PopupManager.zIndex中獲取的,當要展示一個新的彈出框時,組件便會去獲取最新的PopupManager.zIndex,然后為PopupManager.zIndex加1,這樣就保證了新的彈出框總是比舊的彈出框z-index大,省去自己一個個設置的麻煩,也減少問題的出現。
2.遇到的問題
element本身的彈出框沒有什么問題,問題在於我們擅自使用了element未直接暴露出來的組件,這里以el-select中的select-dropdown.vue為例。
我們通過拷貝el-select源碼來定制下拉框的內容和邏輯,一切看起來都很完美,但是有一個致命的問題,自己定制的選擇器的下拉框總是會出現時不時無法展示的問題,要瘋狂點擊才會展示。排查后發現就是z-index的值問題,自定義的下拉框的z-index總是無法跟原生的彈出框z-index同步,原因其實很簡單。。。使用的不是同一個PopupManager
原來我們直接復制el-select源碼,源碼中引入下拉框import ElSelectMenu from './select-dropdown.vue'
我們修改為import ElSelectMenu from 'element-ui/packages/select/src/select-dropdown.vue'
再來看select-dropdown.vue源碼中對於vue-popper的引用import Popper from 'element-ui/src/utils/vue-popper'
沒毛病,但是其實毛病就出在這引用路徑上的src,src就是source源的意思,源碼中互相引用沒問題,但是我們在項目中使用element組件的使用,並不是來自源碼,而是來自源碼編譯出來的依賴庫,是npm模塊中lib目錄下的文件。所以我們的自定義組件用了一個新的PopupManager對象跟原生element組件不同的PopupManager,導致zIndex不同步,展示錯誤。
3.解決
復制select-dropdown.vue,將原先import Popper from 'element-ui/src/utils/vue-popper'
修改為import Popper from 'element-ui/lib/utils/vue-popper'
el-select改引用為我們修改后的select-dropdown.vue。。。
4.最后
- 1.es6中import的每個模塊都是單例的,同一個對象被所有引用共用
- 2.引用element中未暴露的組件時,要注意盡量使用lib下的,防止出現類似問題
- 3.引用npm包的某個文件時時,要注意引用其源碼和編譯后庫的區別