feat: 完成情绪博物馆项目重构和功能增强 - 新增日记评论和帖子功能 - 重构前端架构,优化用户体验 - 完善WebSocket通信机制 - 更新项目文档和部署配置
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* 加载状态管理组合式函数
|
||||
*/
|
||||
|
||||
import { ref, computed } from 'vue'
|
||||
import { ElLoading } from 'element-plus'
|
||||
import type { LoadingInstance } from 'element-plus/es/components/loading/src/loading'
|
||||
|
||||
// 全局加载状态
|
||||
const globalLoading = ref(false)
|
||||
const loadingCount = ref(0)
|
||||
|
||||
/**
|
||||
* 使用加载状态
|
||||
*/
|
||||
export const useLoading = (initialState = false) => {
|
||||
const loading = ref(initialState)
|
||||
|
||||
/**
|
||||
* 设置加载状态
|
||||
*/
|
||||
const setLoading = (state: boolean) => {
|
||||
loading.value = state
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始加载
|
||||
*/
|
||||
const startLoading = () => {
|
||||
loading.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束加载
|
||||
*/
|
||||
const stopLoading = () => {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步操作包装器
|
||||
*/
|
||||
const withLoading = async <T>(fn: () => Promise<T>): Promise<T> => {
|
||||
try {
|
||||
startLoading()
|
||||
return await fn()
|
||||
} finally {
|
||||
stopLoading()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
loading: computed(() => loading.value),
|
||||
setLoading,
|
||||
startLoading,
|
||||
stopLoading,
|
||||
withLoading
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用全局加载状态
|
||||
*/
|
||||
export const useGlobalLoading = () => {
|
||||
/**
|
||||
* 增加加载计数
|
||||
*/
|
||||
const addLoading = () => {
|
||||
loadingCount.value++
|
||||
globalLoading.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少加载计数
|
||||
*/
|
||||
const removeLoading = () => {
|
||||
loadingCount.value = Math.max(0, loadingCount.value - 1)
|
||||
if (loadingCount.value === 0) {
|
||||
globalLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置加载状态
|
||||
*/
|
||||
const resetLoading = () => {
|
||||
loadingCount.value = 0
|
||||
globalLoading.value = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局异步操作包装器
|
||||
*/
|
||||
const withGlobalLoading = async <T>(fn: () => Promise<T>): Promise<T> => {
|
||||
try {
|
||||
addLoading()
|
||||
return await fn()
|
||||
} finally {
|
||||
removeLoading()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
globalLoading: computed(() => globalLoading.value),
|
||||
loadingCount: computed(() => loadingCount.value),
|
||||
addLoading,
|
||||
removeLoading,
|
||||
resetLoading,
|
||||
withGlobalLoading
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用页面加载遮罩
|
||||
*/
|
||||
export const usePageLoading = () => {
|
||||
let loadingInstance: LoadingInstance | null = null
|
||||
|
||||
/**
|
||||
* 显示页面加载遮罩
|
||||
*/
|
||||
const showPageLoading = (options?: {
|
||||
text?: string
|
||||
background?: string
|
||||
target?: string | HTMLElement
|
||||
}) => {
|
||||
const {
|
||||
text = '加载中...',
|
||||
background = 'rgba(0, 0, 0, 0.7)',
|
||||
target = 'body'
|
||||
} = options || {}
|
||||
|
||||
loadingInstance = ElLoading.service({
|
||||
lock: true,
|
||||
text,
|
||||
background,
|
||||
target
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏页面加载遮罩
|
||||
*/
|
||||
const hidePageLoading = () => {
|
||||
if (loadingInstance) {
|
||||
loadingInstance.close()
|
||||
loadingInstance = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面异步操作包装器
|
||||
*/
|
||||
const withPageLoading = async <T>(
|
||||
fn: () => Promise<T>,
|
||||
options?: {
|
||||
text?: string
|
||||
background?: string
|
||||
target?: string | HTMLElement
|
||||
}
|
||||
): Promise<T> => {
|
||||
try {
|
||||
showPageLoading(options)
|
||||
return await fn()
|
||||
} finally {
|
||||
hidePageLoading()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
showPageLoading,
|
||||
hidePageLoading,
|
||||
withPageLoading
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用按钮加载状态
|
||||
*/
|
||||
export const useButtonLoading = () => {
|
||||
const buttonLoadings = ref<Record<string, boolean>>({})
|
||||
|
||||
/**
|
||||
* 设置按钮加载状态
|
||||
*/
|
||||
const setButtonLoading = (key: string, loading: boolean) => {
|
||||
buttonLoadings.value[key] = loading
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取按钮加载状态
|
||||
*/
|
||||
const getButtonLoading = (key: string) => {
|
||||
return computed(() => buttonLoadings.value[key] || false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 按钮异步操作包装器
|
||||
*/
|
||||
const withButtonLoading = async <T>(
|
||||
key: string,
|
||||
fn: () => Promise<T>
|
||||
): Promise<T> => {
|
||||
try {
|
||||
setButtonLoading(key, true)
|
||||
return await fn()
|
||||
} finally {
|
||||
setButtonLoading(key, false)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
buttonLoadings: computed(() => buttonLoadings.value),
|
||||
setButtonLoading,
|
||||
getButtonLoading,
|
||||
withButtonLoading
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用延迟加载
|
||||
*/
|
||||
export const useDelayedLoading = (delay = 300) => {
|
||||
const loading = ref(false)
|
||||
const actualLoading = ref(false)
|
||||
let timer: NodeJS.Timeout | null = null
|
||||
|
||||
/**
|
||||
* 设置加载状态(带延迟)
|
||||
*/
|
||||
const setLoading = (state: boolean) => {
|
||||
if (state) {
|
||||
// 立即设置实际加载状态
|
||||
actualLoading.value = true
|
||||
|
||||
// 延迟显示加载UI
|
||||
timer = setTimeout(() => {
|
||||
loading.value = true
|
||||
}, delay)
|
||||
} else {
|
||||
// 立即隐藏加载UI
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
timer = null
|
||||
}
|
||||
loading.value = false
|
||||
actualLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟异步操作包装器
|
||||
*/
|
||||
const withDelayedLoading = async <T>(fn: () => Promise<T>): Promise<T> => {
|
||||
try {
|
||||
setLoading(true)
|
||||
return await fn()
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
loading: computed(() => loading.value),
|
||||
actualLoading: computed(() => actualLoading.value),
|
||||
setLoading,
|
||||
withDelayedLoading
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user