This commit is contained in:
oneao committed 2025-09-12 17:32:27 +08:00
1 parent 14f9844430
commit 785bce1907
27 files changed
+1051 -175

No files matched your search

@@ -23,14 +23,16 @@ $popup-prefix: '#{$prefix}-popup';
content: '';
position: absolute;
inset: 0;
background: $bg-color-container;
background-color: $bg-color-container;
transform: rotate(45deg);
transform-origin: center;
}
}
&-content {
padding: 4px 8px;
}
// 上方弹出,箭头在底部
&[data-popup-placement^='top'] > &-arrow {
bottom: -4px;
@@ -53,11 +53,11 @@ export default defineComponent({
type: Boolean,
default: false,
},
popupClass: {
class: {
type: [String, Array, Object],
default: '',
},
popupStyle: {
style: {
type: Object,
default: () => ({}),
},
@@ -65,6 +65,8 @@ export default defineComponent({
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
default: '',
},
showDelay: { type: Number, default: 0 },
hideDelay: { type: Number, default: 0 },
},
emits: ['update:visible'],
setup(props, { slots, emit }) {
@@ -75,6 +77,10 @@ export default defineComponent({
const arrowRef = ref<HTMLElement | null>(null) // 箭头引用
const localVisible = ref(props.visible)
const hasRendered = ref(props.visible)
// 定时器
let showTimer: number | null = null
let hideTimer: number | null = null
let cleanup: (() => void) | null = null
const { floatingStyles, middlewareData, placement, update } = useFloating(
@@ -135,43 +141,65 @@ export default defineComponent({
floatEl.style.width = `${triggerEl.offsetWidth}px`
}
const clearTimers = () => {
if (showTimer) {
clearTimeout(showTimer)
showTimer = null
}
if (hideTimer) {
clearTimeout(hideTimer)
hideTimer = null
}
}
const showPopup = async () => {
if (!hasRendered.value)
hasRendered.value = true
await nextTick()
clearTimers()
showTimer = window.setTimeout(async () => {
if (!hasRendered.value)
hasRendered.value = true
await nextTick()
fitFloatingWidth()
localVisible.value = true
setupAutoUpdate()
emit('update:visible', true)
fitFloatingWidth()
localVisible.value = true
setupAutoUpdate()
emit('update:visible', true)
}, props.showDelay)
}
const hidePopup = async () => {
localVisible.value = false
clearAutoUpdate()
emit('update:visible', false)
clearTimers()
hideTimer = window.setTimeout(() => {
localVisible.value = false
clearAutoUpdate()
emit('update:visible', false)
}, props.hideDelay)
}
const togglePopup = async () => {
clearTimers()
if (!hasRendered.value)
hasRendered.value = true
await nextTick()
fitFloatingWidth()
localVisible.value = !localVisible.value
await nextTick()
if (localVisible.value) {
setupAutoUpdate()
if (!localVisible.value) {
// 需要显示
showTimer = window.setTimeout(async () => {
localVisible.value = true
await nextTick()
setupAutoUpdate()
emit('update:visible', true)
}, props.showDelay)
}
else {
clearAutoUpdate()
// 需要隐藏
hideTimer = window.setTimeout(() => {
localVisible.value = false
clearAutoUpdate()
emit('update:visible', false)
}, props.hideDelay)
}
emit('update:visible', localVisible.value)
}
// 事件绑定
@@ -306,11 +334,11 @@ export default defineComponent({
<div
v-show={localVisible.value}
ref={floatingRef}
class={[prefixCls, props.popupClass]}
class={[prefixCls, props.class]}
style={{
...floatingStyles.value,
position: 'absolute',
...props.popupStyle,
...props.style,
}}
data-popup-placement={placement.value}
>