first commit
This commit is contained in:
107
resources/js/Composables/useApiForm.js
Normal file
107
resources/js/Composables/useApiForm.js
Normal file
@@ -0,0 +1,107 @@
|
||||
// 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user