import { watch, PropType, onMounted, onUnmounted, CSSProperties, defineComponent, } from 'vue'; // Utils import { createNamespace, isDef, UnknownProp } from '../utils'; import { lockClick } from './lock-click'; // Components import { Icon } from '../icon'; import { Popup } from '../popup'; import { Loading, LoadingType } from '../loading'; const [name, bem] = createNamespace('toast'); export type ToastType = 'text' | 'loading' | 'success' | 'fail' | 'html'; export type ToastPosition = 'top' | 'middle' | 'bottom'; export default defineComponent({ name, props: { icon: String, show: Boolean, overlay: Boolean, message: [Number, String], iconSize: [Number, String], className: UnknownProp, iconPrefix: String, loadingType: String as PropType, forbidClick: Boolean, overlayClass: UnknownProp, overlayStyle: Object as PropType, closeOnClick: Boolean, closeOnClickOverlay: Boolean, type: { type: String as PropType, default: 'text', }, duration: { type: Number, default: 2000, }, position: { type: String as PropType, default: 'middle', }, transition: { type: String, default: 'van-fade', }, }, emits: ['update:show'], setup(props, { emit }) { let timer: NodeJS.Timeout; let clickable = false; const toggleClickable = () => { const newValue = props.show && props.forbidClick; if (clickable !== newValue) { clickable = newValue; lockClick(clickable); } }; const updateShow = (show: boolean) => emit('update:show', show); const onClick = () => { if (props.closeOnClick) { updateShow(false); } }; const clearTimer = () => { clearTimeout(timer); }; const renderIcon = () => { const { icon, type, iconSize, iconPrefix, loadingType } = props; const hasIcon = icon || type === 'success' || type === 'fail'; if (hasIcon) { return ( ); } if (type === 'loading') { return ( ); } }; const renderMessage = () => { const { type, message } = props; if (isDef(message) && message !== '') { return type === 'html' ? (
) : (
{message}
); } }; watch(() => [props.show, props.forbidClick], toggleClickable); watch( () => [props.show, props.duration], () => { clearTimer(); if (props.show && props.duration > 0) { timer = setTimeout(() => { updateShow(false); }, props.duration); } } ); onMounted(toggleClickable); onUnmounted(toggleClickable); return () => ( {renderIcon()} {renderMessage()} ); }, });