refactor(deps): migrate to nuxt v4
This commit is contained in:
113
app/components/uni/Message/Provider.vue
Normal file
113
app/components/uni/Message/Provider.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<script lang="ts" setup>
|
||||
import type {
|
||||
Message,
|
||||
MessageApi,
|
||||
MessageProviderApi,
|
||||
MessageType,
|
||||
} from '~/components/uni/Message/index'
|
||||
|
||||
const props = defineProps({
|
||||
max: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
})
|
||||
|
||||
const nuxtApp = useNuxtApp()
|
||||
const messageList = ref<Message[]>([])
|
||||
|
||||
const createMessage = (
|
||||
content: string,
|
||||
type: MessageType,
|
||||
duration: number = 3000
|
||||
) => {
|
||||
const { max } = props
|
||||
messageList.value.push({
|
||||
id: (Date.now() + Math.random() * 100).toString(32).toUpperCase(),
|
||||
content,
|
||||
type,
|
||||
duration,
|
||||
})
|
||||
if (messageList.value.length > max) {
|
||||
messageList.value.shift()
|
||||
}
|
||||
}
|
||||
|
||||
const providerApi: MessageProviderApi = {
|
||||
destroy: (id: string) => {
|
||||
messageList.value.splice(
|
||||
messageList.value.findIndex((message) => message.id === id),
|
||||
1
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
const api: MessageApi = {
|
||||
info: (content: string, duration: number = 3000) => {
|
||||
createMessage(content, 'info', duration)
|
||||
},
|
||||
success: (content: string, duration: number = 3000) => {
|
||||
createMessage(content, 'success', duration)
|
||||
},
|
||||
warning: (content: string, duration: number = 3000) => {
|
||||
createMessage(content, 'warning', duration)
|
||||
},
|
||||
error: (content: string, duration: number = 3000) => {
|
||||
createMessage(content, 'error', duration)
|
||||
},
|
||||
destroyAll: function (): void {
|
||||
throw new Error('Function not implemented.')
|
||||
},
|
||||
}
|
||||
|
||||
nuxtApp.vueApp.provide('uni-message-provider', providerApi)
|
||||
nuxtApp.vueApp.provide('uni-message', api)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<slot />
|
||||
<teleport to="body">
|
||||
<div id="message-provider">
|
||||
<div class="message-wrapper">
|
||||
<TransitionGroup name="message">
|
||||
<UniMessage
|
||||
v-for="(message, k) in messageList"
|
||||
:key="message.id"
|
||||
:message="message"
|
||||
/>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#message-provider .message-wrapper {
|
||||
@apply z-[50000] fixed inset-0 flex flex-col items-center pointer-events-none;
|
||||
}
|
||||
|
||||
.message-move,
|
||||
.message-leave-active {
|
||||
transition: all 0.6s ease;
|
||||
}
|
||||
|
||||
.message-enter-active {
|
||||
transition: all 0.6s cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
}
|
||||
|
||||
.message-enter-from {
|
||||
filter: blur(2px);
|
||||
opacity: 0;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.message-leave-to {
|
||||
filter: blur(6px);
|
||||
opacity: 0;
|
||||
transform: translateY(-20%);
|
||||
}
|
||||
|
||||
.message-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
20
app/components/uni/Message/index.d.ts
vendored
Normal file
20
app/components/uni/Message/index.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
export type Message = {
|
||||
id: string
|
||||
content: string
|
||||
type: MessageType
|
||||
duration?: number
|
||||
}
|
||||
|
||||
export type MessageType = 'success' | 'warning' | 'error' | 'info'
|
||||
|
||||
export type MessageProviderApi = {
|
||||
destroy: (id: string) => void
|
||||
}
|
||||
|
||||
export type MessageApi = {
|
||||
info: (content: string, duration?: number) => void
|
||||
success: (content: string, duration?: number) => void
|
||||
warning: (content: string, duration?: number) => void
|
||||
error: (content: string, duration?: number) => void
|
||||
destroyAll: () => void
|
||||
}
|
||||
82
app/components/uni/Message/index.vue
Normal file
82
app/components/uni/Message/index.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<script lang="ts" setup>
|
||||
import type {
|
||||
Message,
|
||||
MessageProviderApi,
|
||||
} from '~/components/uni/Message/index'
|
||||
|
||||
const providerApi = inject<MessageProviderApi>('uni-message-provider')
|
||||
|
||||
const props = defineProps({
|
||||
message: {
|
||||
require: true,
|
||||
type: Object,
|
||||
},
|
||||
})
|
||||
|
||||
const message = ref<Message>(props.message as Message)
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
providerApi?.destroy(message.value.id)
|
||||
}, message.value?.duration || 3000)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="message"
|
||||
:class="{
|
||||
'!text-blue-500 !border-blue-400 !bg-blue-50': message.type === 'info',
|
||||
'!text-emerald-500 !border-emerald-400 !bg-emerald-50':
|
||||
message.type === 'success',
|
||||
'!text-orange-500 !border-orange-400 !bg-orange-50':
|
||||
message.type === 'warning',
|
||||
'!text-rose-500 !border-rose-400 !bg-rose-50': message.type === 'error',
|
||||
[message.type]: message.type,
|
||||
}"
|
||||
>
|
||||
<UniIconCircleSuccess
|
||||
v-if="message.type === 'success'"
|
||||
class="text-xl"
|
||||
/>
|
||||
<UniIconCircleWarning
|
||||
v-if="message.type === 'warning'"
|
||||
class="text-xl"
|
||||
/>
|
||||
<UniIconCircleError
|
||||
v-if="message.type === 'error'"
|
||||
class="text-xl"
|
||||
/>
|
||||
<UniIconCircleInfo
|
||||
v-if="message.type === 'info'"
|
||||
class="text-xl"
|
||||
/>
|
||||
<span>
|
||||
{{ message.content }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.message {
|
||||
min-width: 80px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
@apply h-fit px-2 py-1.5 border bg-white border-gray-300 rounded-md text-gray-500 text-xs flex items-center gap-1.5 first-of-type:mt-2.5 mt-2.5 font-bold pointer-events-auto;
|
||||
}
|
||||
|
||||
.message.info {
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.message.success {
|
||||
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.message.warning {
|
||||
box-shadow: 0 4px 12px rgba(249, 115, 22, 0.2);
|
||||
}
|
||||
|
||||
.message.error {
|
||||
box-shadow: 0 4px 12px rgba(244, 63, 94, 0.2);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user