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里找到的,怪不得大家在技术选型时都要提倡所选的库要社区活跃。