108 lines
3.0 KiB
JavaScript
108 lines
3.0 KiB
JavaScript
// composables/useSmartApiForm.js
|
|
import { ref, reactive, watch } from 'vue'
|
|
import axios from 'axios'
|
|
|
|
export function useApiForm(initialData = {}) {
|
|
const loading = ref(false)
|
|
const errors = ref({})
|
|
const progress = ref(0)
|
|
|
|
// Для обычных полей формы
|
|
const formData = ref({ ...initialData })
|
|
// Для файлов
|
|
const files = ref({})
|
|
|
|
const setFile = (fieldName, file) => {
|
|
files.value[fieldName] = file
|
|
// Автоматически очищаем ошибку для этого поля
|
|
clearError(fieldName)
|
|
}
|
|
|
|
const clearError = (field) => {
|
|
if (errors.value[field]) {
|
|
const newErrors = { ...errors.value }
|
|
delete newErrors[field]
|
|
errors.value = newErrors
|
|
}
|
|
}
|
|
|
|
const clearAllErrors = () => {
|
|
errors.value = {}
|
|
}
|
|
|
|
const submit = async (url, method = 'post', config = {}) => {
|
|
loading.value = true
|
|
progress.value = 0
|
|
clearAllErrors()
|
|
|
|
try {
|
|
// Создаем FormData
|
|
const formDataToSend = new FormData()
|
|
|
|
// Добавляем обычные поля формы
|
|
Object.keys(formData.value).forEach(key => {
|
|
if (formData.value[key] !== null && formData.value[key] !== undefined) {
|
|
formDataToSend.append(key, formData.value[key])
|
|
}
|
|
})
|
|
|
|
// Добавляем файлы
|
|
Object.keys(files.value).forEach(key => {
|
|
if (files.value[key]) {
|
|
formDataToSend.append(key, files.value[key])
|
|
}
|
|
})
|
|
|
|
const response = await axios({
|
|
method,
|
|
url,
|
|
data: formDataToSend,
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
...config.headers
|
|
},
|
|
onUploadProgress: (progressEvent) => {
|
|
if (progressEvent.total) {
|
|
progress.value = Math.round(
|
|
(progressEvent.loaded * 100) / progressEvent.total
|
|
)
|
|
}
|
|
},
|
|
...config
|
|
})
|
|
|
|
return response.data
|
|
} catch (error) {
|
|
if (error.response?.status === 422) {
|
|
errors.value = error.response.data.errors || {}
|
|
}
|
|
throw error
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const reset = () => {
|
|
// Сбрасываем обычные поля
|
|
Object.keys(initialData).forEach(key => {
|
|
formData.value[key] = initialData[key]
|
|
})
|
|
// Сбрасываем файлы
|
|
files.value = {}
|
|
clearAllErrors()
|
|
}
|
|
|
|
return {
|
|
formData,
|
|
files,
|
|
errors,
|
|
loading,
|
|
progress,
|
|
submit,
|
|
setFile,
|
|
clearError,
|
|
clearAllErrors,
|
|
reset
|
|
}
|
|
}
|