SwFile
Компонент SwFile — загрузчик файлов с двумя режимами: photo (фото и видео с пред-просмотром и обрезкой) и document (документы с просмотром в отдельном окне браузера). Поддерживает drag & drop и выбор через системный диалог.
Режимы / Modes
| Режим | mode | Описание / Description |
|---|---|---|
| Фото | photo | image/, video/ — один файл, предпросмотр, обрезка области. |
| Документы | document | PDF, Word, Excel и др. — несколько файлов, клик открывает в новой вкладке. |
Свойства / Properties
| Имя | Тип | По умолчанию | Значения/Описание |
|---|---|---|---|
mode | String | photo | 'photo' | 'document'. |
disabled | Boolean | false | Блокировка загрузки и удаления. |
accept | String | `` | Переопределение accept у <input type="file">. По умолчанию зависит от mode. |
label | String | `` | Заголовок зоны загрузки. |
class | String | `` | Дополнительный CSS-класс корневого элемента. |
aspectRatio | Number | null | null | Соотношение сторон области обрезки в режиме photo (например 1, 16/9). |
editorTitle | String[] | см. описание | Заголовки редактора: По умолчанию ['Preview', 'Preview and crop', 'Preview and crop video']. |
Модель / Model
v-model — массив объектов File[] (итоговые файлы после обрезки или без неё).
События / Events
| Имя | Параметры | Описание |
|---|---|---|
change | files: File[] | Срабатывает при изменении списка файлов в модели. |
remove | file: File, index | Удаление файла из списка. |
preview | file: File | В режиме document — перед открытием в новом окне. |
Слоты / Slots
| Имя | Описание / Description |
|---|---|
| default | Текст зоны загрузки; scope: { mode, label }. |
data | Имя и размер файла в списке; scope: { item, file, index, size }. |
remove | Вся кнопка удаления; scope: { item, file, index, disabled, onClick }. |
close | Вся кнопка закрытия; scope: { onClick }. |
skip-crop | Вся кнопка без обрезки; scope: { processing, onClick }. |
apply | Вся кнопка применения; scope: { processing, onClick }. |
Особенности реализации
Режим photo
- После выбора файла открывается модальное окно с пред-просмотром.
- Для изображений обрезка выполняется через
canvas. - Для видео обрезка области записывается через
canvas+MediaRecorder(результат —webm, если браузер поддерживает). - Область обрезки можно перемещать и менять размер угловыми ручками.
- Кнопка skip-crop добавляет исходный файл без изменений.
Режим document
- Файлы отображаются списком с именем и размером.
- Можно выбрать или перетащить несколько файлов за один раз.
- Клик по элементу открывает файл в новой вкладке.
Пример использования / Example Usage
<script setup>
import { ref } from 'vue'
const photoFiles = ref([])
const documentFiles = ref([])
</script>
<!-- Фото / видео -->
<sw-file
v-model="photoFiles"
mode="photo"
:aspect-ratio="1"
label="Загрузить фото или видео"
:editor-title="[
'Предпросмотр',
'Предпросмотр и обрезка',
'Предпросмотр и обрезка видео'
]"
>
<template #default="{ label }">
<span class="sw-file-drop-title">{{ label }}</span>
<span class="sw-file-drop-hint">Перетащите файл или нажмите для выбора</span>
</template>
<template #data="{ file, size }">
<span class="sw-file-item-name">{{ file.name }}</span>
<span class="sw-file-item-meta">{{ size }}</span>
</template>
<template #remove="{ onClick, disabled }">
<sw-button type="danger" text :disabled="disabled" @click="onClick">Удалить</sw-button>
</template>
<template #skip-crop="{ onClick, processing }">
<sw-button text :disabled="processing" @click="onClick">Без обрезки</sw-button>
</template>
<template #apply="{ onClick, processing }">
<sw-button type="primary" :disabled="processing" @click="onClick">
{{ processing ? 'Обработка…' : 'Применить' }}
</sw-button>
</template>
</sw-file>
<!-- Документы -->
<sw-file
v-model="documentFiles"
mode="document"
label="Загрузить документы"
>
<template #default="{ label }">
<span class="sw-file-drop-title">{{ label }}</span>
<span class="sw-file-drop-hint">PDF, Word, Excel — можно выбрать несколько файлов сразу</span>
</template>
<template #data="{ file, size }">
<span class="sw-file-item-name">{{ file.name }}</span>
<span class="sw-file-item-meta">{{ size }}</span>
</template>
<template #remove="{ onClick, disabled }">
<sw-button type="danger" text :disabled="disabled" @click="onClick">Удалить</sw-button>
</template>
</sw-file>