UNPKG

sard-uniapp

Version:

sard-uniapp 是一套基于 Uniapp + Vue3 框架开发的兼容多端的 UI 组件库

138 lines (137 loc) 4.03 kB
import { ref, onMounted, onUnmounted, watch, computed } from 'vue'; const tickInterval = 30; export function useTransition(options = {}) { const duration = computed(() => { return options.duration || 0; }); const enterFromClass = computed(() => { return options.enterFromClass || `${options.prefix}enter-from`; }); const enterActiveClass = computed(() => { return options.enterActiveClass || `${options.prefix}enter-active`; }); const enterToClass = computed(() => { return options.enterToClass || `${options.prefix}enter-to`; }); const leaveFromClass = computed(() => { return options.leaveFromClass || `${options.prefix}leave-from`; }); const leaveActiveClass = computed(() => { return options.leaveActiveClass || `${options.prefix}leave-active`; }); const leaveToClass = computed(() => { return options.leaveToClass || `${options.prefix}leave-to`; }); const realVisible = ref(false); const transitionClass = ref(''); let status = ''; let timer; let tickTimer; function nextTick(callback) { tickTimer = setTimeout(() => { tickTimer = null; callback(); }, tickInterval); } function clearAllTimeout() { if (tickTimer) { clearTimeout(tickTimer); tickTimer = null; } if (timer) { clearTimeout(timer); timer = null; } } function callHook(name) { options.onVisibleHook?.(name); } function enter() { clearAllTimeout(); if (status === 'leaving') { callHook('leave-cancelled'); } status = 'entering'; realVisible.value = true; transitionClass.value = `${enterFromClass.value} ${enterActiveClass.value}`; callHook('before-enter'); nextTick(() => { transitionClass.value = `${enterActiveClass.value} ${enterToClass.value}`; callHook('enter'); }); timer = setTimeout(() => { timer = null; if (status === 'entering' && options.visible) { entered(); } }, duration.value + tickInterval); } function entered() { clearAllTimeout(); status = 'entered'; transitionClass.value = ''; callHook('after-enter'); } function leave() { clearAllTimeout(); if (status === 'entering') { callHook('enter-cancelled'); } status = 'leaving'; transitionClass.value = `${leaveFromClass.value} ${leaveActiveClass.value}`; callHook('before-leave'); nextTick(() => { transitionClass.value = `${leaveActiveClass.value} ${leaveToClass.value}`; callHook('leave'); }); timer = setTimeout(() => { timer = null; if (status === 'leaving' && !options.visible) { leaved(); } }, duration.value + tickInterval); } function leaved() { clearAllTimeout(); status = 'leaved'; transitionClass.value = ''; realVisible.value = false; callHook('after-leave'); } function onTransitionEnd() { if (status === 'entering' && options.visible) { entered(); } else if (status === 'leaving' && !options.visible) { leaved(); } } onMounted(() => { if (options.visible) { enter(); } }); onUnmounted(() => { if (timer) { clearTimeout(timer); timer = null; } if (tickTimer) { clearTimeout(tickTimer); tickTimer = null; } }); watch(() => options.visible, () => { if (options.visible) { enter(); } else { leave(); } }); return { onTransitionEnd, realVisible, transitionClass, }; }