fix(bom): remove teleported false and use dynamic scroll listener to fix invisible dropdown in table
This commit is contained in:
@ -67,9 +67,8 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="isEditMode"
|
:disabled="isEditMode"
|
||||||
class="beautified-select"
|
class="beautified-select"
|
||||||
:teleported="false"
|
popper-class="bom-loadmore-popper"
|
||||||
@visible-change="(visible: boolean) => handleVisibleChange(visible, 'parent')"
|
@visible-change="(visible: boolean) => handleVisibleChange(visible, 'parent')"
|
||||||
v-loadmore="loadMoreParent"
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in parentOptions"
|
v-for="item in parentOptions"
|
||||||
@ -148,9 +147,8 @@
|
|||||||
:loading="selectLoading"
|
:loading="selectLoading"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:loading-text="`正在加载第 ${childQueryParams.page} 页...`"
|
:loading-text="`正在加载第 ${childQueryParams.page} 页...`"
|
||||||
:teleported="false"
|
popper-class="bom-loadmore-popper"
|
||||||
@visible-change="(visible: boolean) => handleVisibleChange(visible, 'child', $index)"
|
@visible-change="(visible: boolean) => handleVisibleChange(visible, 'child', $index)"
|
||||||
v-loadmore="(el: HTMLElement) => loadMoreChild(el, $index)"
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in getChildOptions($index)"
|
v-for="item in getChildOptions($index)"
|
||||||
@ -209,56 +207,6 @@ import { getBomList, getBomDetail, saveBom, deleteBom } from '@/api/bom'
|
|||||||
import { getMaterialBaseList } from '@/api/inbound/stock'
|
import { getMaterialBaseList } from '@/api/inbound/stock'
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
// v-loadmore 自定义指令(局部注册)
|
|
||||||
// 用于监听 Element Plus 下拉面板的滚动触底事件
|
|
||||||
// ============================================================
|
|
||||||
const vLoadmore = {
|
|
||||||
mounted(el: HTMLElement, binding: any) {
|
|
||||||
// 找到 .el-select-dropdown__wrap(滚动容器)
|
|
||||||
const targetSelector = '.el-select-dropdown:not(.is-hidden) .el-select-dropdown__wrap'
|
|
||||||
|
|
||||||
const scrollHandler = () => {
|
|
||||||
const scrollContainer = el.querySelector(targetSelector) as HTMLElement | null
|
|
||||||
if (!scrollContainer) return
|
|
||||||
|
|
||||||
const { scrollTop, scrollHeight, clientHeight } = scrollContainer
|
|
||||||
const distanceToBottom = scrollHeight - scrollTop - clientHeight
|
|
||||||
|
|
||||||
// 距离底部 10px 以内时触发加载更多
|
|
||||||
if (distanceToBottom <= 10) {
|
|
||||||
binding.value(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用 MutationObserver 监听 DOM 变化(Element Plus 下拉弹窗是动态创建的)
|
|
||||||
const observer = new MutationObserver(() => {
|
|
||||||
const dropdown = el.querySelector('.el-select-dropdown:not(.is-hidden)') as HTMLElement | null
|
|
||||||
if (dropdown) {
|
|
||||||
const wrap = dropdown.querySelector('.el-select-dropdown__wrap') as HTMLElement | null
|
|
||||||
if (wrap) {
|
|
||||||
wrap.removeEventListener('scroll', scrollHandler)
|
|
||||||
wrap.addEventListener('scroll', scrollHandler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
observer.observe(el, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true
|
|
||||||
})
|
|
||||||
|
|
||||||
// 存储清理函数
|
|
||||||
;(el as any)._loadmoreObserver = observer
|
|
||||||
},
|
|
||||||
unmounted(el: HTMLElement) {
|
|
||||||
const observer = (el as any)._loadmoreObserver
|
|
||||||
if (observer) {
|
|
||||||
observer.disconnect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// 类型定义
|
// 类型定义
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@ -434,6 +382,30 @@ const handleVisibleChange = (visible: boolean, type: 'parent' | 'child', index?:
|
|||||||
state.hasMore = true
|
state.hasMore = true
|
||||||
fetchMaterialOptions('child', index)
|
fetchMaterialOptions('child', index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 动态绑定触底滚动事件
|
||||||
|
nextTick(() => {
|
||||||
|
const popperWrap = document.querySelector('.bom-loadmore-popper:not(.is-hidden) .el-select-dropdown__wrap') as HTMLElement;
|
||||||
|
if (popperWrap) {
|
||||||
|
// 先解绑可能存在的旧事件,防止重复触发
|
||||||
|
if ((popperWrap as any)._scrollHandler) {
|
||||||
|
popperWrap.removeEventListener('scroll', (popperWrap as any)._scrollHandler);
|
||||||
|
}
|
||||||
|
// 定义滚动触发逻辑
|
||||||
|
(popperWrap as any)._scrollHandler = function() {
|
||||||
|
const { scrollTop, scrollHeight, clientHeight } = this;
|
||||||
|
// 距离底部 10px 触发
|
||||||
|
if (scrollHeight - scrollTop - clientHeight <= 10) {
|
||||||
|
if (type === 'parent') {
|
||||||
|
loadMoreParent();
|
||||||
|
} else if (type === 'child' && index !== undefined) {
|
||||||
|
loadMoreChild(popperWrap, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
popperWrap.addEventListener('scroll', (popperWrap as any)._scrollHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user