背景
element-plus中,el-select中可选项达到了500条,页面跳转销毁时导致异常卡顿(vue3.0.0版本,3.0.11版本有很大改善,建议升级)
因此需要进行分页操作。初步设想时当select中的options滚动到最底部的时候,触发加载更多,获取更多的可选项。
实现方式
打算通过指令实现,这样添加就很方便,预期一个指令
1 | v-loadmore="loadMore" |
搜一下
正常情况下,我们碰到的100个需求,99个都已经有人实现过了,所以我们就只需要搜一哈,就能找到答案。
果不其然,答案异常的多,只不过都是element-ui的,不过改动不多,应该问题不大,让我们来试一试。
开始踩坑
1.附上随处可搜的代码
我就不贴从哪抄的了,因为随处可以搜到
1 | Vue.directive('loadMore', { |
这个代码分析起来很简单
1.通过指令绑定的时候传递dom节点
2.再通过class选择器找到scroll的盒子节点
3.添加滚动监听事件
4.滚动到底,触发绑定事件
在element-ui上完美运行
但是
在element-plus不行,会提示找不到SELECTWRAP_DOM
因为SELECTWRAP_DOM
为null,所以添加监听器就报错了
探寻不同
1.对比element-ui和element-plus的dom节点
左边是element-ui,右边是element-plus
节点都在,而且都在body下,按道理应该没问题
2.打印挂载的el节点
发现了没,plus下打印的节点,异常清爽,并且还有两行贴心的注释
1 | <!--teleport start--> |
3.vue3新增了Teleport
在vue3刚出来的时候,我读过一遍文档,依稀记得添加了一个神奇的控件Teleport
,可以把逻辑和展示分开,但是是它的逻辑在一块。
想必element-plus就是使用这种方式重构了select组件。
4.阅读源码
让我们翻开element-plus/packages/select/src/select.vue
映入眼帘的就是el-popper
我们再看看element-plus/packages/popper/src/index.vue
看来我们找到它了
5.定位联系
我们点击select
,唤起对应的待选列表
如果一个页面有多个select
,也是正常能唤起的
所以每个select
与每个popper
之间,应该存在着某种联系
继续阅读el-popper
,果然,我们发现了一个值popperId
并且被赋值给了ariaDescribedby
回过头来看dom🌲
我们果然在select的标签上,找到了ariaDescribedby
属性
并且再其对应的popper
上,找到了这个id
那么问题解决了,我们只需要对指令稍作修改
最终指令
1 | const loadMore = { |