新增:全量优化

This commit is contained in:
yuantao
2025-11-05 16:20:06 +08:00
parent ca6bf7f211
commit 65656f1810
27 changed files with 2407 additions and 292 deletions

7
hooks/index.js Normal file
View File

@@ -0,0 +1,7 @@
/**
* Hooks统一导出入口
*/
export { useRequest } from './useRequest.js'
export { useState, useStorageState, useFormState } from './useState.js'
export { useGet, usePost } from './useApi.js'

157
hooks/useApi.js Normal file
View File

@@ -0,0 +1,157 @@
import { ref, reactive } from 'vue'
import { http } from '@/api/index.js'
import tool from '@/common/utils/tool.js'
/**
* GET请求Hook
* @param {string} url 请求URL
* @param {Object} options 配置选项
* @returns {Object} 请求相关状态和方法
*/
export function useGet(url, options = {}) {
const {
manual = false, // 是否手动触发
params = {}, // 请求参数
cache = false, // 是否使用缓存
loadingDelay = 0, // loading延迟时间
onSuccess = () => {}, // 成功回调
onError = () => {}, // 失败回调
} = options
// 状态
const data = ref(null)
const loading = ref(false)
const error = ref(null)
// loading延迟定时器
let loadingTimer = null
/**
* 执行GET请求
* @param {Object} requestParams 请求参数
*/
async function run(requestParams = {}) {
// 清除之前的loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
// 如果有loading延迟先启动定时器
if (loadingDelay > 0) {
loadingTimer = setTimeout(() => {
loading.value = true
}, loadingDelay)
} else {
loading.value = true
}
try {
const response = await http.get(url, {
params: { ...params, ...requestParams },
cache,
})
// 清除loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
data.value = response.data
error.value = null
onSuccess(response.data)
return response.data
} catch (err) {
// 清除loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
error.value = err
data.value = null
console.error(`GET请求失败: ${url}`, err)
onError(err)
throw err
} finally {
loading.value = false
}
}
/**
* 取消请求
*/
function cancel() {
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
loading.value = false
}
// 如果不是手动触发,立即执行
if (!manual) {
Promise.resolve().then(() => {
run(params)
})
}
return {
data,
loading,
error,
run,
cancel,
}
}
/**
* POST请求Hook
* @param {string} url 请求URL
* @returns {Object} 请求相关状态和方法
*/
export function usePost(url) {
/**
* 执行POST请求
* @param {Object} data 请求数据
* @param {Object} options 配置选项
*/
async function run(data, options = {}) {
const { loadingDelay = 0, onSuccess = () => {}, onError = () => {} } = options
let loadingTimer = null
// 如果有loading延迟先启动定时器
if (loadingDelay > 0) {
loadingTimer = setTimeout(() => {
tool.loading()
}, loadingDelay)
} else {
tool.loading()
}
try {
const response = await http.post(url, data)
// 清除loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
tool.hideLoading()
onSuccess(response.data)
return response.data
} catch (err) {
// 清除loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
tool.hideLoading()
console.error(`POST请求失败: ${url}`, err)
onError(err)
throw err
}
}
return {
run,
}
}

113
hooks/useRequest.js Normal file
View File

@@ -0,0 +1,113 @@
import { ref, reactive } from 'vue'
import tool from '@/common/utils/tool.js'
/**
* 通用请求Hook
* @param {Function} apiFunction API函数
* @param {Object} options 配置选项
* @returns {Object} 请求相关状态和方法
*/
export function useRequest(apiFunction, options = {}) {
const {
manual = false, // 是否手动触发
defaultParams = [], // 默认参数
onSuccess = () => {}, // 成功回调
onError = () => {}, // 失败回调
loadingDelay = 0, // loading延迟时间
} = options
// 状态
const data = ref(null)
const loading = ref(false)
const error = ref(null)
const params = ref([])
// loading延迟定时器
let loadingTimer = null
/**
* 执行请求
* @param {...any} args 请求参数
*/
async function run(...args) {
// 清除之前的loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
// 设置参数
params.value = args
// 如果有loading延迟先启动定时器
if (loadingDelay > 0) {
loadingTimer = setTimeout(() => {
loading.value = true
}, loadingDelay)
} else {
loading.value = true
}
try {
const result = await apiFunction(...args)
// 清除loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
data.value = result
error.value = null
onSuccess(result, args)
return result
} catch (err) {
// 清除loading延迟定时器
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
error.value = err
data.value = null
console.error('请求失败:', err)
onError(err, args)
throw err
} finally {
loading.value = false
}
}
/**
* 取消请求
*/
function cancel() {
if (loadingTimer) {
clearTimeout(loadingTimer)
loadingTimer = null
}
loading.value = false
}
/**
* 重新执行请求
*/
function refresh() {
return run(...params.value)
}
// 如果不是手动触发,立即执行
if (!manual) {
// 使用nextTick确保在组件挂载后执行
Promise.resolve().then(() => {
run(...defaultParams)
})
}
return {
data,
loading,
error,
params,
run,
cancel,
refresh,
}
}

140
hooks/useState.js Normal file
View File

@@ -0,0 +1,140 @@
import { ref, computed } from 'vue'
import tool from '@/common/utils/tool.js'
/**
* 状态管理Hook
* @param {any} initialState 初始状态
* @returns {Object} 状态和操作方法
*/
export function useState(initialState) {
const state = ref(initialState)
/**
* 设置状态
* @param {any} newState 新状态
*/
function setState(newState) {
if (typeof newState === 'function') {
state.value = newState(state.value)
} else {
state.value = newState
}
}
/**
* 重置状态到初始值
*/
function resetState() {
state.value = typeof initialState === 'function' ? initialState() : initialState
}
return {
state: computed(() => state.value),
setState,
resetState,
}
}
/**
* 本地存储状态Hook
* @param {string} key 存储键名
* @param {any} defaultValue 默认值
* @returns {Object} 状态和操作方法
*/
export function useStorageState(key, defaultValue = null) {
const storageValue = tool.storage(key) ?? defaultValue
const { state, setState, resetState } = useState(storageValue)
/**
* 设置状态并同步到本地存储
* @param {any} newState 新状态
*/
function setStorageState(newState) {
if (typeof newState === 'function') {
newState = newState(state.value)
}
setState(newState)
tool.storage(key, newState)
}
/**
* 清除本地存储中的值
*/
function clearStorage() {
tool.removeStorage(key)
resetState()
}
return {
state,
setState: setStorageState,
resetState: () => {
clearStorage()
},
clearStorage,
}
}
/**
* 表单状态Hook
* @param {Object} initialFormData 初始表单数据
* @returns {Object} 表单状态和操作方法
*/
export function useFormState(initialFormData = {}) {
const { state, setState, resetState } = useState({ ...initialFormData })
/**
* 设置表单项
* @param {string} field 字段名
* @param {any} value 字段值
*/
function setField(field, value) {
setState(prev => ({
...prev,
[field]: value,
}))
}
/**
* 重置表单到初始状态
*/
function resetForm() {
resetState()
}
/**
* 清空表单
*/
function clearForm() {
setState({})
}
/**
* 批量设置表单值
* @param {Object} values 表单值对象
*/
function setFields(values) {
setState(prev => ({
...prev,
...values,
}))
}
/**
* 获取表单验证器
* @returns {Object} 验证器实例
*/
function getValidator() {
return tool.getValidator()
}
return {
form: state,
setField,
resetForm,
clearForm,
setFields,
getValidator,
}
}