1. 背景
在之前做的一個項目中使用到了element的級聯選擇器,并且是需要懶加載、多選、父子不關聯等等,在選的時候當然沒問題,但是回顯的時候就會回顯不出來,相信大部分伙伴都遇到過這個問題。我在以前出過一篇文章寫過關于級聯選擇器在動態加載時的回顯解決。el-cascader級聯選擇器動態加載時的回顯解決-源碼解析
我在當時提出了兩種解決方案,第一種是“初始化時調接口渲染panel”,第二種是“改交互”。在element-plus中的級聯選擇器的動態加載中,其實是支持了回顯的,用的方法其實就是第一種“初始化時調接口渲染panel”。現在看看element和elemengplus中cascader的區別。
2. 問題
2.1 elementplus中cascader級聯選擇器的回顯
2.1.1 elementplus的cascader本身就支持回顯了
在element和elemengplus中的cascader的initStore方法有一個重要區別:
elementUI:
圖1
element-plus: 看圖2,在element-plus中新加了一個syncCheckedValue方法,光看這個名字就知道大概的功能,異步選中節點的值。再看圖3,有一個forEach方法,然后遞歸調用lazyLoad方法,將syncCheckedValue方法作為回調函數傳入lazyLoad方法。再看圖4的lazyLoad方法,將syncCheckedValue方法在resolve中調用了。總之,這幾個方法運行后就會回顯懶加載的數據。
圖2
圖3
?
圖4?
但是正如我之前在那篇文章里說的,多選時這種做法是不現實的,只有單選的時候適用。
圖5?
2.2.2 我的解決方法
如我之前那篇文章所示,我也是通過改交互,并且借鑒了之前說過的lazyCascader的交互,但是具體邏輯改成了適用于我們業務的邏輯。具體組件如下所示。核心邏輯就是把回顯框與選擇的panel解偶。具體代碼大家可以訪問我上面那篇文章鏈接,里面有貼lazyCascader的地址。
圖6?
2.2 cascader多選時選中節點后會回彈到頂部選中節點處
2.2.1?scrollIntoView
死去的回憶突然攻擊我!最近在用elementplus的cascader懶加載回顯,又遇到了這個問題。之前在vue2就遇到過這個問題,所以我一下就找到了原因,全是因為cascader中的這個函數:
scrollIntoView
圖7?
這個問題在社區的issue中有很多個朋友問過。有element的,也有elementPlus中的。關于為什么會執行這個syncMenuState方法,具體看這個issue的評論區的回答。[Bug Report] el-cascader 選中會自動跳到第一次選中位置 #21947
先說一下我的情況,我的情況是我沒用cascader的lazy方法,而是自己將接口請求回的數據用遞歸塞到了options里,就導致了options的變化。然后見如下elementPlus中cascade的源碼執行順序:
options變化 -> initStore -> syncCheckedValue -> syncMenuState -> scrollToExpandingNode -> scrollIntoView
所以我這種情況,因為人為修改了options,并不是組件內部自己去用懶加載方式去處理options。那么這個函數按照源代碼邏輯是必會執行的。
圖8
?
圖9?
圖10
?
圖11
?
圖12?
2.2.2 解決方法
我這個解決方法有點不講武德,直接copy源代碼到本地,把scrollIntoView注釋掉。我在vue2和vue3兩個版本都是這樣干的。但是我是因為我的邏輯必定會觸發scrollIntoView方法,其余情況大家看下是不是自己的options和value值處理得不對。
vue2: 10月前。
圖13?
vue3:?
圖14?
復制下來用需要修改一下源碼的一些引入路徑。
比如這種,在源代碼中寫的是相對路徑../store.mjs,那么需要將這種全部改為絕對路徑,讓資源去從nodemodule的element-plus中找。
圖15?
3. 總結
這就是最近使用elementPlus的cascader遇到的兩個問題,希望能幫助到大家。ps:我發現遇到這種第三方庫的問題去github上看issue還是挺有用的,之前時間選擇器遇到個問題也是去issue里找到的,怪不得大家在技術選型時都要提倡所選的庫要社區活躍。