ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vue3全局提示(Message)

Vue3全局提示(Message) Vue2全局提示Message可自定义设置以下属性提示内容content类型string默认 undefined自动关闭的延时duration类型number单位 ms设置 null 时不自动关闭默认 3000消息距离顶部的位置top类型string | number单位 px默认 30调用一次只展示一个提示调用多次则依次展示多个按照调用先后顺序依次自动关闭。效果如下图open()调用info()调用success()调用error()调用warning()调用loading()调用在线预览①创建全局提示组件Message其中引入使用了以下工具函数使用requestAnimationFrame模拟实现setTimeout和setInterval获取依赖注入 useInjectscript setup langts import { ref, computed, watch, onBeforeUnmount } from vue import type { CSSProperties, VNode } from vue import { rafTimeout, cancelRaf, useInject } from components/utils export interface Props { content?: string // 提示内容 duration?: number // 自动关闭的延时单位 ms设置 null 时不自动关闭 top?: string | number // 消息距离顶部的位置单位 px } const props withDefaults(definePropsProps(), { content: undefined, duration: 3000, top: 30 }) export interface Message { content?: string // 提示内容 icon?: VNode // 自定义图标 duration?: number | null // 自动关闭的延时时长单位 ms设置 null 时不自动关闭 top?: string | number // 消息距离顶部的位置单位 px class?: string // 自定义类名 style?: CSSProperties // 自定义样式 onClick?: Function // 点击 message 时的回调函数 onClose?: Function // 关闭时的回调函数 [propName: string]: any // 用于包含带有任意数量的其他属性 } const resetTimer ref() const showMessage refboolean[]([]) const hideTimers refany[]([]) const messageContent refMessage[]([]) const closeDuration refnumber | null(null) // 自动关闭延时 const messageTop refstring() // message 距离顶部的位置 const { colorPalettes } useInject(Message) // 主题色注入 const emits defineEmits([click, close]) // 所有提示是否已经全部变为 false const clear computed(() { return showMessage.value.every((show: boolean) !show) }) watch(clear, (to, from) { // 所有提示都消失后重置 if (!from to) { resetTimer.value rafTimeout(() { messageContent.value [] showMessage.value [] }, 300) } }) onBeforeUnmount(() { hideTimers.value.forEach((rafId: any) { rafId cancelRaf(rafId) }) }) function onEnter(index: number): void { hideTimers.value[index] cancelRaf(hideTimers.value[index]) } function onLeave(index: number): void { hideMessage(index) } function onClick(e: Event, index: number): void { messageContent.value[index].onClick messageContent.value[index].onClick() emits(click, e) } function hideMessage(index: number): void { if (closeDuration.value ! null) { hideTimers.value[index] rafTimeout(() { showMessage.value[index] false hideTimers.value[index] null messageContent.value[index].onClose messageContent.value[index].onClose() emits(close) }, closeDuration.value) } } function show(): void { resetTimer.value cancelRaf(resetTimer.value) const index messageContent.value.length - 1 const last messageContent.value[index] if (last.top ! undefined) { messageTop.value typeof last.top number ? ${last.top}px : last.top } else { messageTop.value typeof props.top number ? ${props.top}px : props.top } showMessage.value[index] true if (last.duration ! null) { closeDuration.value last.duration || props.duration hideMessage(index) } else { closeDuration.value null } } function open(message: string | Message): void { if (typeof message string) { messageContent.value.push({ content: message, mode: open }) } else { messageContent.value.push({ ...message, mode: open }) } show() } function info(message: string | Message): void { if (typeof message string) { messageContent.value.push({ content: message, mode: info }) } else { messageContent.value.push({ ...message, mode: info }) } show() } function success(message: string | Message): void { if (typeof message string) { messageContent.value.push({ content: message, mode: success }) } else { messageContent.value.push({ ...message, mode: success }) } show() } function error(message: string | Message): void { if (typeof message string) { messageContent.value.push({ content: message, mode: error }) } else { messageContent.value.push({ ...message, mode: error }) } show() } function warning(message: string | Message): void { if (typeof message string) { messageContent.value.push({ content: message, mode: warning }) } else { messageContent.value.push({ ...message, mode: warning }) } show() } function loading(message: string | Message): void { if (typeof message string) { messageContent.value.push({ content: message, mode: loading }) } else { messageContent.value.push({ ...message, mode: loading }) } show() } defineExpose({ open, info, success, error, warning, loading }) /script template div classmessage-wrap :style top: ${messageTop}; --message-primary-color: ${colorPalettes[5]}; --message-success-color: #52c41a; --message-warning-color: #faad14; --message-error-color: #ff4d4f; TransitionGroup nameslide-fade div v-showshowMessage[index] classmessage-container :classmessage.class :stylemessage.style v-for(message, index) in messageContent :keyindex div classmessage-content-wrap :classicon-${message.mode} mouseenteronEnter(index) mouseleaveonLeave(index) clickonClick($event, index) component v-ifmessage.icon :ismessage.icon classicon-svg / svg v-else-ifmessage.mode info classicon-svg focusablefalse >script setup langts import Message from ./Message.vue import { ref, h } from vue import { SoundFilled, FireFilled } from ant-design/icons-vue const message ref() const customMessage ref() function onOpen(content: string) { message.value.open(content) // open 调用 } function onInfo(content: string) { message.value.info(content) // info 调用 } function onSuccess(content: string) { message.value.success(content) // success 调用 } function onError(content: string) { message.value.error(content) // error 调用 } function onWarning(content: string) { message.value.warning(content) // warning 调用 } function onLoading(content: string) { message.value.loading(content) // loading 调用 } function onInfoCustom(content: string) { // info 调用, 并自定义图标 message.value.info({ content, icon: h(SoundFilled) }) } function onOpenCustom(content: string) { // open 调用, 并自定义图标 message.value.open({ content, icon: h(FireFilled, { style: color: gold }) }) } function onClassCustom(content: string) { message.value.info({ content, icon: h(SoundFilled), class: custom-class }) } function onStyleCustom(content: string) { customMessage.value.warning({ content, icon: h(FireFilled), top: 30vh, style: { color: #f50 } }) } function onCustomClose() { message.value.info({ content: The message will automatically turn off after 3 seconds., duration: 3000, onClose: () { console.log(custom message closed) } }) } function onNeverAutoClose() { message.value.info({ content: This message will not automatically turn off., duration: null, onClick: () { console.log(custom message clicked) } }) } function onClick(e: Event) { console.log(click, e) } function onClose() { console.log(close) } /script template div h1{{ $route.name }} {{ $route.meta.title }}/h1 h2 classmt30 mb10基本使用/h2 Button typeprimary clickonOpen(This is a noraml message)Open/Button h2 classmt30 mb10不同类型的全局提示/h2 Space Button typeprimary clickonInfo(This is an info message)Info/Button Button typeprimary clickonSuccess(This is a success message)Success/Button Button typeprimary clickonError(This is an error message)Error/Button Button typeprimary clickonWarning(This is a warning message)Warning/Button Button typeprimary clickonLoading(This is a loading message)Loading/Button /Space h2 classmt30 mb10自定义图标/h2 Space Button typeprimary clickonInfoCustom(This is a custom icon message)Custom Info Icon/Button Button typeprimary clickonOpenCustom(This is a custom icon message)Custom Icon/Button /Space h2 classmt30 mb10自定义样式/h2 Space Button typeprimary clickonClassCustom(This is a custom class message)Custom Class/Button Button typeprimary clickonStyleCustom(This is a custom style message)Custom Style/Button /Space h2 classmt30 mb10自定义关闭延时/h2 Space Button typeprimary clickonCustomCloseCustom Close/Button Button typeprimary clickonNeverAutoCloseNever Auto Close/Button /Space Message refmessage clickonClick closeonClose / Message refcustomMessage clickonClick closeonClose / /div /template style langless scoped :deep(.custom-class) { color: #ff6900; } /style
返回列表