Перейти к содержимому

delay —— нормализация задержки показа/скрытия

Tooltip требуется «показывать сразу при наведении указателя, а при уходе — скрывать с небольшой паузой» (чтобы избежать мерцания при проведении); popconfirm — «появляется сразу по клику». У каждого плавающего компонента свой ритм показа/скрытия, но «какое значение по умолчанию использовать, когда пользователь не передал» — вопрос общий.

  • Плавающие слои, реагирующие на наведение: tooltip / popover / popconfirm и подобные, props открывают show-delay / hide-delay.
  • Любой временной параметр, который «пользователь может переопределить, но у него есть разумное значение по умолчанию».

Не следует использовать: для фиксированных ритмов (автоматическое закрытие message через 3 секунды) — пишите константу напрямую, нормализация не нужна.

import { resolveDelay, type LhDefaultDelay } from '@lh-ui/share/core/shared/delay'
export interface LhDefaultDelay {
show: number
hide: number
}
Функция Сигнатура Назначение
resolveDelay (showDelay: number | undefined, hideDelay: number | undefined, defaults: LhDefaultDelay) => LhDefaultDelay нормализация задержки показа/скрытия
resolveDelay(undefined, undefined, { show: 0, hide: 150 })
// { show: 0, hide: 150 } —— пользователь не передал, используются значения компонента по умолчанию
resolveDelay(200, undefined, { show: 0, hide: 150 })
// { show: 200, hide: 150 } —— переопределён только show

Реализация — это два ??: showDelay ?? defaults.show, hideDelay ?? defaults.hide. null проходит тем же путём (?? обрабатывает и null, и undefined).

У трёх компонентов разные значения по умолчанию, но одинаковая логика нормализации:

Компонент show по умолчанию hide по умолчанию Причина
tooltip 0 150 появляется сразу, чтобы не было «наведения без отклика»; задержка скрытия избегает мерцания при движении к цели
popover 0 150 то же, но содержимое интерактивно, hide больше (задаётся UI-слоем)
popconfirm 0 0 срабатывание по клику, семантики наведения нет

После выделения функции новый плавающий компонент просто передаёт свои defaults, и не нужно писать ещё одну реализацию «отката undefined».

Две легко путаемые вещи:

resolveDelay debounce (utils)
Семантика нормализация параметров «сколько ждать перед показом / скрытием» инструмент throttling, сворачивающий частые вызовы в одно выполнение
Применение вычислить значение задержки обернуть с этим значением настоящий таймер

Типичная цепочка — последовательная: const { hide } = resolveDelay(props.hideDelay, undefined, DEFAULTS) → hideTimer = debounce(actualHide, hide).

// внутри компонента popover
const DEFAULT_DELAY: LhDefaultDelay = { show: 0, hide: 150 }
const delay = computed(() =>
resolveDelay(props.showDelay, props.hideDelay, DEFAULT_DELAY),
)
function onShow() {
setTimeout(open, delay.value.show)
}
function onHide() {
setTimeout(close, delay.value.hide)
}
  • Только откат, без клампинга: отрицательная задержка возвращается как есть. Если UI-слою нужно «задержка неотрицательная», это обрабатывается на месте через setTimeout(fn, Math.max(0, ms)) (setTimeout воспринимает отрицательные значения как 0, так что реально проблем не возникает).
  • show / hide независимы: после нормализации это два независимых числа, компонент использует их в двух разных таймерах.
  • Возвращается новый объект: каждый вызов возвращает новый { show, hide }, который можно безопасно оборачивать в реактивность.
@lh-ui/share/core/delay → resolveDelay( )
返回值
(填好参数后点运行)

Copyright © 2024-2026 FengMo WenXue