updates
This commit is contained in:
parent
b046ea95d0
commit
3b457cf1c2
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
### `src/utils/message.ts`
|
||||
- **Purpose**: Provides a global interface for showing toast messages.
|
||||
- **Methods**: `success(msg, duration)`, `error(msg, duration)`, `warning(msg, duration)`, `info(msg, duration)`.
|
||||
- **Methods**: `success(msg, duration, position)`, `error(msg, duration, position)`, `warning(msg, duration, position)`, `info(msg, duration, position)`.
|
||||
- **Implementation**: Programmatically mounts `WMessage.vue`.
|
||||
- **New Feature**: Supports `position` argument: `'top-center' | 'top-left' | 'top-right' | 'bottom-center' | 'bottom-left' | 'bottom-right'`.
|
||||
|
||||
### `src/service/request/index.ts`
|
||||
- **Purpose**: Encapsulates Axios for API requests.
|
||||
|
|
|
|||
|
|
@ -34,3 +34,10 @@
|
|||
- **Goal**: Ensure score data is fetched when ScoreForm mounts if store is empty.
|
||||
- **Scope**:
|
||||
- `src/components/ScoreForm.vue` (Update onMounted)
|
||||
|
||||
### [Task 3] Enhance WMessage Component
|
||||
- **Time**: 2025-12-18
|
||||
- **Goal**: Add position configuration support (top/bottom/left/right/center).
|
||||
- **Scope**:
|
||||
- `src/utils/message.ts` (Update logic to support multiple containers)
|
||||
- `src/components/ui/WMessage.vue` (No changes needed, styles handled by container)
|
||||
|
|
|
|||
|
|
@ -22,3 +22,6 @@
|
|||
- [x] Create `src/stores/score.ts` <!-- id: 18 -->
|
||||
- [x] Integrate Get Score in `TheNavigation.vue` <!-- id: 19 -->
|
||||
- [x] Integrate Save Score in `ScoreForm.vue` <!-- id: 20 -->
|
||||
|
||||
- [x] [Task 3] Enhance WMessage Component <!-- id: 21 -->
|
||||
- [x] Add position support to `src/utils/message.ts` (top/bottom/left/right/center) <!-- id: 22 -->
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ function close() {
|
|||
visible.value = false
|
||||
// Give time for transition to finish before removing
|
||||
setTimeout(() => {
|
||||
// props.onClose(props.id)
|
||||
props.onClose(props.id)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,8 +118,8 @@ class Request {
|
|||
return this.instance.request(config)
|
||||
}
|
||||
|
||||
get<T = any>(url: string, config?: CustomRequestConfig): Promise<T> {
|
||||
return this.instance.get(url, config)
|
||||
get<T = any>(url: string, params?: any, config?: CustomRequestConfig): Promise<T> {
|
||||
return this.instance.get(url, { ...config, params })
|
||||
}
|
||||
|
||||
post<T = any>(url: string, data?: any, config?: CustomRequestConfig): Promise<T> {
|
||||
|
|
|
|||
|
|
@ -5,22 +5,42 @@ let seed = 1
|
|||
const instances: any[] = []
|
||||
|
||||
type MessageType = 'success' | 'error' | 'warning' | 'info'
|
||||
export type MessagePosition = 'top-center' | 'top-left' | 'top-right' | 'bottom-center' | 'bottom-left' | 'bottom-right'
|
||||
|
||||
interface MessageOptions {
|
||||
message: string
|
||||
type?: MessageType
|
||||
duration?: number
|
||||
position?: MessagePosition
|
||||
}
|
||||
|
||||
const positionClasses: Record<MessagePosition, string> = {
|
||||
'top-center': 'top-4 left-1/2 transform -translate-x-1/2 flex-col items-center',
|
||||
'top-left': 'top-4 left-4 flex-col items-start',
|
||||
'top-right': 'top-4 right-4 flex-col items-end',
|
||||
'bottom-center': 'bottom-4 left-1/2 transform -translate-x-1/2 flex-col-reverse items-center',
|
||||
'bottom-left': 'bottom-4 left-4 flex-col-reverse items-start',
|
||||
'bottom-right': 'bottom-4 right-4 flex-col-reverse items-end',
|
||||
}
|
||||
|
||||
const Message = (options: MessageOptions) => {
|
||||
const { position = 'top-center' } = options
|
||||
const id = `message_${seed++}`
|
||||
const container = document.createElement('div')
|
||||
|
||||
// Create a container for the message if it doesn't exist
|
||||
let messageContainer = document.querySelector('.w-message-container')
|
||||
// We need separate containers for each position
|
||||
const containerClass = `w-message-container-${position}`
|
||||
let messageContainer = document.querySelector(`.${containerClass}`)
|
||||
|
||||
if (!messageContainer) {
|
||||
messageContainer = document.createElement('div')
|
||||
messageContainer.className = 'w-message-container fixed top-4 left-1/2 transform -translate-x-1/2 z-50 flex flex-col items-center pointer-events-none'
|
||||
// Common classes
|
||||
let classes = `w-message-container ${containerClass} fixed z-50 flex pointer-events-none transition-all duration-300`
|
||||
// Position specific classes
|
||||
classes += ` ${positionClasses[position]}`
|
||||
|
||||
messageContainer.className = classes
|
||||
document.body.appendChild(messageContainer)
|
||||
}
|
||||
|
||||
|
|
@ -28,37 +48,30 @@ const Message = (options: MessageOptions) => {
|
|||
...options,
|
||||
id,
|
||||
onClose: () => {
|
||||
close(id, container)
|
||||
close(id, container, position)
|
||||
},
|
||||
}
|
||||
|
||||
const vnode = createVNode(WMessage, props)
|
||||
|
||||
// Render the component into the container
|
||||
// We append the container to the messageContainer
|
||||
messageContainer.appendChild(container)
|
||||
render(vnode, container)
|
||||
|
||||
instances.push({ id, vnode, container })
|
||||
instances.push({ id, vnode, container, position })
|
||||
}
|
||||
|
||||
function close(id: string, container: HTMLElement) {
|
||||
function close(id: string, container: HTMLElement, position: string) {
|
||||
const idx = instances.findIndex(vm => vm.id === id)
|
||||
if (idx === -1) return
|
||||
|
||||
const { vnode } = instances[idx]
|
||||
// Manually call close on component if needed, but here we just unmount
|
||||
// The component handles its own visibility transition
|
||||
|
||||
// We wait for the transition to finish? The component calls onClose after transition.
|
||||
// So we just remove it from DOM.
|
||||
|
||||
render(null, container)
|
||||
container.remove()
|
||||
instances.splice(idx, 1)
|
||||
|
||||
// Clean up container if empty
|
||||
const messageContainer = document.querySelector('.w-message-container')
|
||||
const containerClass = `w-message-container-${position}`
|
||||
const messageContainer = document.querySelector(`.${containerClass}`)
|
||||
if (messageContainer && messageContainer.childNodes.length === 0) {
|
||||
messageContainer.remove()
|
||||
}
|
||||
|
|
@ -66,10 +79,10 @@ function close(id: string, container: HTMLElement) {
|
|||
|
||||
// Helpers
|
||||
export const message = {
|
||||
success: (msg: string, duration?: number) => Message({ message: msg, type: 'success', duration }),
|
||||
error: (msg: string, duration?: number) => Message({ message: msg, type: 'error', duration }),
|
||||
warning: (msg: string, duration?: number) => Message({ message: msg, type: 'warning', duration }),
|
||||
info: (msg: string, duration?: number) => Message({ message: msg, type: 'info', duration }),
|
||||
success: (msg: string, duration?: number, position?: MessagePosition) => Message({ message: msg, type: 'success', duration, position }),
|
||||
error: (msg: string, duration?: number, position?: MessagePosition) => Message({ message: msg, type: 'error', duration, position }),
|
||||
warning: (msg: string, duration?: number, position?: MessagePosition) => Message({ message: msg, type: 'warning', duration, position }),
|
||||
info: (msg: string, duration?: number, position?: MessagePosition) => Message({ message: msg, type: 'info', duration, position }),
|
||||
}
|
||||
|
||||
export default message
|
||||
|
|
|
|||
Loading…
Reference in New Issue