barneo-file-service
v1.1.1
Published
Комплексная библиотека Vue 3 для работы с файлами в приложениях Barneo. Предоставляет мощную функциональность для загрузки, управления и обработки файлов с валидацией, отслеживанием прогресса и поддержкой localStorage.
Maintainers
Readme
Barneo File Service
Комплексная библиотека Vue 3 для работы с файлами в приложениях Barneo. Предоставляет мощную функциональность для загрузки, управления и обработки файлов с валидацией, отслеживанием прогресса и поддержкой localStorage.
Версия: 1.1.1
Дата релиза: 2 сентября 2025
Лицензия: MIT
🚀 Основные возможности
- Загрузка файлов: Поддержка drag & drop, множественной загрузки
- Валидация: Проверка размера, типа и количества файлов
- Отслеживание прогресса: Детальная информация о процессе загрузки
- Управление состоянием: Реактивное состояние файлов и ошибок
- Хранилище: Сохранение файлов в localStorage для повторного использования
- Обработка ошибок: Возможность повтора неудачных загрузок
- Кастомизация: Гибкая настройка через props, slots и события
📦 Установка
npm install barneo-file-service🔧 Быстрый старт
1. Подключение плагина
import { createApp } from "vue";
import BarneoFileService from "barneo-file-service";
import { AppName } from "barneo-file-service";
import "barneo-file-service/style";
const app = createApp(App);
app.use(BarneoFileService, {
apiUrl: "https://api.example.com/upload",
appName: AppName.PIM,
maxFiles: 10,
maxFileSize: 50 * 1024 * 1024, // 50MB
allowedTypes: ["image/jpeg", "image/png", "application/pdf"],
onUploadSuccess: (results) => console.log("Файлы загружены:", results),
});
app.mount("#app");2. Базовое использование компонента
<template>
<FileUploader
title="Загрузить документы"
@upload-success="handleUploadSuccess"
@upload-error="handleUploadError"
/>
</template>
<script setup>
const handleUploadSuccess = (files) => {
console.log("Загружено файлов:", files.length);
};
const handleUploadError = (error) => {
console.error("Ошибка загрузки:", error);
};
</script>🎯 Сценарии использования
1. Загрузка документов с валидацией
<template>
<FileUploader
title="Загрузить документы"
:max-files="5"
:max-file-size="10 * 1024 * 1024"
:allowed-types="['application/pdf', 'application/msword']"
@upload-success="handleDocumentsUpload"
/>
</template>
<script setup>
const handleDocumentsUpload = (files) => {
// Обработка загруженных документов
files.forEach((file) => {
console.log(`Документ загружен: ${file.originalName}`);
});
};
</script>2. Загрузка изображений с предпросмотром
<template>
<FileUploader
button-type="input"
title="Загрузить изображения"
:allowed-types="['image/jpeg', 'image/png', 'image/webp']"
:multiple="true"
@upload-success="handleImagesUpload"
/>
</template>
<script setup>
const handleImagesUpload = (files) => {
// Создание предпросмотра изображений
files.forEach((file) => {
const img = new Image();
img.src = file.url;
// Добавление в галерею
});
};
</script>3. Использование с кастомным UI
<template>
<FileUploader
button-type="default"
button-text="Выбрать файлы"
button-variant="primary"
@upload-success="handleUpload"
>
<template #button="{ openModal, buttonText }">
<button @click="openModal" class="custom-button">
{{ buttonText }}
</button>
</template>
<template #modal-header="{ title, closeModal }">
<div class="custom-header">
<h2>{{ title }}</h2>
<button @click="closeModal">✕</button>
</div>
</template>
</FileUploader>
</template>4. Работа с сохраненными файлами
<template>
<FileUploader title="Управление файлами" @upload-success="handleUpload" />
</template>
<script setup>
import { useFileService } from "barneo-file-service";
const fileService = useFileService();
const handleUpload = (files) => {
// Файлы автоматически сохраняются в localStorage
console.log("Файлы сохранены в хранилище");
// Получение сохраненных файлов
const storedFiles = fileService.storedFiles.value;
console.log("Сохраненные файлы:", storedFiles);
};
</script>5. Управление загруженными файлами через props
<template>
<FileUploader
button-type="input"
:uploaded-files="myUploadedFiles"
@files-cleared="handleFilesCleared"
@upload-success="handleUploadSuccess"
/>
</template>
<script setup>
import { ref } from "vue";
const myUploadedFiles = ref([
{
id: 1,
originalName: "document.pdf",
name: "document.pdf",
size: 1024000,
type: "application/pdf",
url: "https://example.com/document.pdf",
},
]);
const handleFilesCleared = () => {
// Файлы были очищены пользователем
console.log("Файлы очищены");
// Здесь можно обновить состояние в родительском компоненте
myUploadedFiles.value = [];
};
const handleUploadSuccess = (files) => {
// Добавляем новые загруженные файлы к существующим
myUploadedFiles.value.push(...files);
};
</script>6. Вызов методов компонента из родительского компонента
<template>
<div>
<button @click="clearFiles">Очистить файлы</button>
<button @click="openModal">Открыть модальное окно</button>
<button @click="closeModal">Закрыть модальное окно</button>
<FileUploader
ref="fileUploaderRef"
button-type="input"
:uploaded-files="myUploadedFiles"
@files-cleared="handleFilesCleared"
/>
</div>
</template>
<script setup>
import { ref } from "vue";
const fileUploaderRef = ref();
const myUploadedFiles = ref([
{
id: 1,
originalName: "document.pdf",
name: "document.pdf",
size: 1024000,
type: "application/pdf",
url: "https://example.com/document.pdf",
},
]);
const clearFiles = () => {
// Вызываем метод clearUploadedFiles из дочернего компонента
fileUploaderRef.value?.clearUploadedFiles();
};
const openModal = () => {
// Открываем модальное окно программно
fileUploaderRef.value?.openModal();
};
const closeModal = () => {
// Закрываем модальное окно программно
fileUploaderRef.value?.closeModal();
};
const handleFilesCleared = () => {
console.log("Файлы очищены");
myUploadedFiles.value = [];
};
</script>📋 API Reference
FileUploader Component
Props
| Prop | Type | Default | Description |
| --------------------- | -------------------------------------------------- | ------------------- | -------------------------------------------------------------- |
| title | string | 'Загрузка файлов' | Заголовок модального окна |
| buttonText | string | 'Загрузить файлы' | Текст кнопки |
| buttonSize | 'small' \| 'medium' \| 'large' | 'medium' | Размер кнопки |
| buttonVariant | 'primary' \| 'secondary' \| 'outline' \| 'ghost' | 'primary' | Стиль кнопки |
| buttonType | 'default' \| 'input' | 'default' | Тип отображения кнопки |
| buttonIcon | string | undefined | CSS класс иконки |
| autoCloseOnSuccess | boolean | true | Автоматически закрывать модальное окно после успешной загрузки |
| showCancelButton | boolean | true | Показывать ли кнопку отмены |
| cancelButtonText | string | 'Отмена' | Текст кнопки отмены |
| modalMaxWidth | string | '600px' | Максимальная ширина модального окна |
| modalPosition | 'center' \| 'top' \| 'bottom' | 'center' | Позиция модального окна |
| closeOnOverlayClick | boolean | true | Закрывать ли модальное окно при клике вне его |
| showAnimations | boolean | true | Показывать ли анимации |
| uploadedFiles | FileUploadResponse[] | undefined | Список загруженных файлов для отображения |
Events
| Event | Payload | Description |
| ----------------- | ---------------------------------- | ------------------------------------------- |
| upload-success | FileUploadResponse[] | Файлы успешно загружены |
| upload-complete | [FileUploadResponse[], string[]] | Загрузка завершена (успешно или с ошибками) |
| upload-error | Error | Ошибка загрузки |
| files-selected | File[] | Файлы выбраны (но еще не загружены) |
| modal-open | void | Модальное окно открыто |
| modal-close | void | Модальное окно закрыто |
| files-cleared | void | Загруженные файлы очищены |
Exposed Methods
Методы, которые можно вызывать из родительского компонента через ref:
| Method | Parameters | Return Type | Description |
| ----------------------- | ---------- | ----------- | ---------------------------- |
| clearUploadedFiles | - | void | Очищает загруженные файлы |
| openModal | - | void | Открывает модальное окно |
| closeModal | - | void | Закрывает модальное окно |
| uploadSelectedFiles | - | Promise | Загружает выбранные файлы |
| clearFiles | - | void | Очищает выбранные файлы |
| clearErrors | - | void | Очищает ошибки валидации |
| clearCompletedUploads | - | void | Очищает завершенные загрузки |
| retryFailedUploads | - | void | Повторяет неудачные загрузки |
Slots
button - Слот для кнопки (по умолчанию)
<template
#button="{ openModal, buttonText, buttonSize, buttonVariant, buttonIcon }"
>
<button @click="openModal" class="custom-button">
{{ buttonText }}
</button>
</template>button-input - Слот для input типа кнопки
<template
#button-input="{
openModal,
title,
uploadedFiles,
clearUploadedFiles,
formatFileSize,
allowedTypes,
}"
>
<div class="custom-input">
<span>{{ title }}</span>
<button @click="openModal">Выбрать</button>
<button @click="clearUploadedFiles">Очистить</button>
</div>
</template>modal-header - Слот для заголовка модального окна
<template #modal-header="{ title, closeModal }">
<div class="custom-header">
<h2>{{ title }}</h2>
<button @click="closeModal">Закрыть</button>
</div>
</template>file-drop-zone - Слот для области выбора файлов
<template
#file-drop-zone="{
selectFiles,
isDragOver,
selectedFiles,
errors,
triggerFileInput,
formatFileSize,
config,
}"
>
<div
@drop="selectFiles"
@dragover.prevent
:class="{ 'drag-over': isDragOver }"
>
<p>Перетащите файлы сюда</p>
<button @click="triggerFileInput">Выбрать файлы</button>
</div>
</template>file-list - Слот для списка выбранных файлов
<template
#file-list="{
selectedFiles,
removeFile,
clearFiles,
isFileUploading,
formatFileSize,
isUploading,
}"
>
<div class="file-list">
<div v-for="(file, index) in selectedFiles" :key="index">
<span>{{ file.name }}</span>
<span>{{ formatFileSize(file.size) }}</span>
<button @click="removeFile(index)" :disabled="isFileUploading(file)">
Удалить
</button>
</div>
</div>
</template>stored-files - Слот для списка сохраненных файлов
<template
#stored-files="{
storedFiles,
selectedStoredFiles,
toggleStoredFileSelection,
isStoredFileSelected,
removeStoredFile,
formatFileSize,
formatDate,
hasStoredFiles,
}"
>
<div v-if="hasStoredFiles" class="stored-files">
<div v-for="file in storedFiles" :key="file.id">
<input
type="checkbox"
:checked="isStoredFileSelected(file.id)"
@change="toggleStoredFileSelection(file.id)"
/>
<span>{{ file.originalName }}</span>
<span>{{ formatFileSize(file.size) }}</span>
<span>{{ formatDate(file.uploadedAt) }}</span>
<button @click="removeStoredFile(file.id)">Удалить</button>
</div>
</div>
</template>action-buttons - Слот для кнопок действий
<template
#action-buttons="{
uploadFiles,
selectStoredFiles,
clearFiles,
retryFailedUploads,
isUploading,
hasSelectedFiles,
hasErrors,
activeMode,
hasSelectedStoredFiles,
closeModal,
showCancelButton,
cancelButtonText,
}"
>
<div class="action-buttons">
<button v-if="showCancelButton" @click="closeModal">
{{ cancelButtonText }}
</button>
<button
v-if="activeMode === 'upload'"
@click="uploadFiles"
:disabled="!hasSelectedFiles || isUploading"
>
{{ isUploading ? "Загрузка..." : "Загрузить" }}
</button>
<button
v-else-if="activeMode === 'select'"
@click="selectStoredFiles"
:disabled="!hasSelectedStoredFiles"
>
Выбрать
</button>
</div>
</template>Composables
useFileService()
Основной composable для работы с файлами.
import { useFileService } from "barneo-file-service";
const fileService = useFileService();
// Состояние
const selectedFiles = fileService.selectedFiles;
const errors = fileService.errors;
const isUploading = fileService.isUploading;
const totalProgress = fileService.totalProgress;
// Методы
const results = await fileService.uploadSelectedFiles();
fileService.selectFiles(files);
fileService.clearFiles();
fileService.clearErrors();useFileInput(options)
Composable для управления выбором файлов.
import { useFileInput } from "barneo-file-service";
const {
selectedFiles,
errors,
selectFiles,
removeFile,
clearFiles,
isFileSelected,
totalSize,
} = useFileInput({
maxFiles: 5,
maxFileSize: 10 * 1024 * 1024, // 10MB
allowedTypes: ["image/jpeg", "image/png"],
multiple: true,
});useFileUploader(options)
Composable для управления загрузкой файлов.
import { useFileUploader } from "barneo-file-service";
const {
uploads,
isUploading,
totalProgress,
uploadFile,
uploadFiles,
retryUpload,
clearUploads,
} = useFileUploader({
apiUrl: "https://api.example.com/upload",
appName: AppName.PIM,
onProgress: (progress) => console.log(`Progress: ${progress}%`),
onError: (error) => console.error("Upload failed:", error),
});useFileStorage()
Composable для управления хранилищем файлов.
import { useFileStorage } from "barneo-file-service";
const {
storedFiles,
selectedStoredFiles,
addStoredFile,
removeStoredFile,
clearStoredFiles,
addSelectedStoredFile,
clearSelectedStoredFiles,
} = useFileStorage();Сервисы
FileUploadService
Сервис для загрузки файлов на сервер.
import { FileUploadService } from "barneo-file-service";
const service = new FileUploadService({
apiUrl: "https://api.example.com/upload",
appName: AppName.PIM,
headers: { Authorization: "Bearer token" },
timeout: 30000,
});
// Загрузка одного файла
const result = await service.uploadFile(file, {
appName: AppName.PIM,
onProgress: (progress) => console.log(`Progress: ${progress}%`),
onError: (error) => console.error("Upload failed:", error),
});
// Загрузка нескольких файлов
const results = await service.uploadFiles([file1, file2], {
appName: AppName.PIM,
});🎨 Кастомизация
CSS переменные
Библиотека использует CSS переменные для кастомизации стилей:
:root {
--primary-color: #0091ea;
--primary-hover: #0077cc;
--gray-50: #fafafa;
--gray-100: #f9fafb;
--gray-200: #f3f4f6;
--gray-300: #e5e7eb;
--gray-400: #d1d5db;
--gray-500: #9ca3af;
--gray-600: #6b7280;
--gray-700: #374151;
--gray-900: #111827;
--error-color: #ef4444;
--success-color: #10b981;
--border-radius-sm: 6px;
--border-radius-md: 8px;
--border-radius-lg: 10px;
--border-radius-xl: 12px;
--transition: all 0.15s ease;
--shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
--shadow-lg: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
}Кастомные стили
<template>
<FileUploader class="custom-uploader" />
</template>
<style>
.custom-uploader {
--primary-color: #ff6b6b;
--border-radius-md: 12px;
}
.custom-uploader .file-uploader__button {
background: linear-gradient(45deg, #ff6b6b, #ee5a24);
border: none;
color: white;
font-weight: bold;
}
</style>🔧 Разработка
# Установка зависимостей
npm install
# Разработка
npm run dev
# Сборка
npm run build
# Проверка типов
npm run type-check
# Линтинг
npm run lint📄 Лицензия
MIT
