Валидация файлов

В библиотеке Naive UI управление файлами осуществляется через компонент n-upload, который позволяет загружать файлы с различными настройками и проверками. Одним из ключевых аспектов работы с файлами является валидация — проверка соответствия загружаемых файлов определённым критериям до их отправки на сервер.


Атрибут before-upload

before-upload — это функция, которая вызывается перед загрузкой каждого файла. Она позволяет выполнять синхронные и асинхронные проверки, возвращая булево значение или Promise<boolean>:

<template>
  <n-upload
    :before-upload="validateFile"
    action="https://example.com/upload"
  >
    <n-button>Загрузить файл</n-button>
  </n-upload>
</template>

<script>
export default {
  methods: {
    validateFile(file) {
      const isAcceptedType = ['image/png', 'image/jpeg'].includes(file.type);
      const isSizeValid = file.size / 1024 / 1024 < 2; // <2MB

      if (!isAcceptedType) {
        this.$message.error('Допустимы только PNG и JPEG файлы');
      }

      if (!isSizeValid) {
        this.$message.error('Размер файла не должен превышать 2MB');
      }

      return isAcceptedType && isSizeValid;
    }
  }
}
</script>

Ключевые моменты:

  • file.type — MIME-тип файла, например image/png.
  • file.size — размер файла в байтах.
  • Можно использовать как синхронную, так и асинхронную проверку через Promise.

Ограничение типов файлов

Для базовой фильтрации можно использовать атрибут accept, который указывает допустимые форматы:

<n-upload accept=".png,.jpg,.jpeg" action="/upload">
  <n-button>Выбрать файл</n-button>
</n-upload>

Важно: accept только ограничивает выбор в диалоговом окне, но не предотвращает программную загрузку неподходящего файла. Поэтому проверка в before-upload остаётся обязательной.


Проверка количества файлов

Компонент n-upload поддерживает параметр max, который ограничивает число файлов в очереди:

<n-upload :max="3" action="/upload">
  <n-button>Загрузить файлы</n-button>
</n-upload>

При превышении лимита пользователю автоматически отображается предупреждение. Для более сложной логики можно контролировать очередь вручную через событие on-change:

<n-upload
  :file-list="fileList"
  @update:file-list="handleFileList"
  action="/upload"
>
  <n-button>Загрузить</n-button>
</n-upload>

<script>
export default {
  data() {
    return {
      fileList: []
    };
  },
  methods: {
    handleFileList(newList) {
      if (newList.length > 3) {
        this.$message.warning('Можно загрузить не более 3 файлов');
        return;
      }
      this.fileList = newList;
    }
  }
}
</script>

Асинхронная валидация

before-upload может возвращать Promise, что позволяет проверять файлы на сервере перед загрузкой:

validateFile(file) {
  return new Promise((resolve) => {
    fetch(`/api/check-file?name=${file.name}`)
      .then(res => res.json())
      .then(data => {
        if (data.exists) {
          this.$message.error('Файл с таким именем уже существует');
          resolve(false);
        } else {
          resolve(true);
        }
      });
  });
}

Такой подход полезен для проверки уникальности имени файла, а также других ограничений, зависящих от серверной логики.


Ограничение размера файла

Для проверки размера файла можно использовать простое условие в before-upload:

validateFile(file) {
  const maxSizeMB = 5;
  if (file.size / 1024 / 1024 > maxSizeMB) {
    this.$message.error(`Файл не должен превышать ${maxSizeMB} MB`);
    return false;
  }
  return true;
}

Размер можно задавать динамически, например через переменные или конфигурацию проекта.


Пользовательские ошибки и сообщения

В Naive UI можно выводить ошибки через встроенный n-message:

import { useMessage } from 'naive-ui';

const message = useMessage();

message.error('Ошибка валидации файла');

Это позволяет создавать динамические уведомления без использования сторонних библиотек.


Валидация нескольких критериев одновременно

Лучшей практикой является комбинирование нескольких проверок: тип, размер, количество файлов, уникальность:

validateFile(file) {
  const isTypeValid = ['image/png', 'image/jpeg'].includes(file.type);
  const isSizeValid = file.size / 1024 / 1024 < 3;
  
  if (!isTypeValid) {
    this.$message.error('Допустимы только PNG и JPEG');
    return false;
  }

  if (!isSizeValid) {
    this.$message.error('Размер файла превышает 3 MB');
    return false;
  }

  return true;
}

Такой подход делает валидацию гибкой и управляемой, снижая вероятность ошибок при загрузке.


Итоговые рекомендации по валидации файлов

  • Использовать before-upload для всех проверок до отправки на сервер.
  • accept служит для фильтрации выбора, но не заменяет полноценную проверку.
  • Контролировать количество файлов через max или вручную через file-list.
  • При необходимости выполнять асинхронную валидацию через Promise.
  • Выводить ошибки через n-message для информирования пользователя.

Эти инструменты позволяют создавать надежную систему загрузки файлов с полной проверкой всех критичных условий.