КРЕАТИВНЫЕ САЙТЫ И ПРИЛОЖЕНИЯ,
КАЧЕСТВЕННЫЕ WEB-УСЛУГИ
phone

SwFile

загрузчик файлов с двумя режимами:
photo и document.

SwFile

Компонент SwFile — загрузчик файлов с двумя режимами: photo (фото и видео с пред-просмотром и обрезкой) и document (документы с просмотром в отдельном окне браузера). Поддерживает drag & drop и выбор через системный диалог.

Режимы / Modes

РежимmodeОписание / Description
Фотоphotoimage/, video/ — один файл, предпросмотр, обрезка области.
ДокументыdocumentPDF, Word, Excel и др. — несколько файлов, клик открывает в новой вкладке.

Свойства / Properties

ИмяТипПо умолчаниюЗначения/Описание
modeStringphoto'photo' | 'document'.
disabledBooleanfalseБлокировка загрузки и удаления.
acceptString``Переопределение accept у <input type="file">. По умолчанию зависит от mode.
labelString``Заголовок зоны загрузки.
classString``Дополнительный CSS-класс корневого элемента.
aspectRatioNumber | nullnullСоотношение сторон области обрезки в режиме photo (например 1, 16/9).
editorTitleString[]см. описаниеЗаголовки редактора: По умолчанию ['Preview', 'Preview and crop', 'Preview and crop video'].

Модель / Model

v-model — массив объектов File[] (итоговые файлы после обрезки или без неё).

События / Events

ИмяПараметрыОписание
changefiles: File[]Срабатывает при изменении списка файлов в модели.
removefile: File, indexУдаление файла из списка.
previewfile: 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>