Работа с файлами в Vue.js строится на взаимодействии компонентов с
объектами File и FileReader браузера, а также
с серверной частью через HTTP-запросы. Vue не предоставляет встроенных
API для работы с файловой системой, но позволяет удобно интегрировать
стандартные веб-технологии и библиотеки.
<input type="file">Для выбора файлов используется стандартный элемент формы:
<input type="file" @change="handleFileUpload" multiple>
multiple позволяет выбирать несколько
файлов.change срабатывает при выборе файлов
пользователем.В методе компонента можно получить доступ к файлам через
event.target.files:
export default {
methods: {
handleFileUpload(event) {
const files = event.target.files;
for (let i = 0; i < files.length; i++) {
console.log(files[i].name, files[i].size, files[i].type);
}
}
}
}
Каждый элемент массива files является объектом
File, содержащим свойства name,
size, type, lastModified.
Для чтения данных из файлов используется объект
FileReader:
handleFileUpload(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onl oad = (e) => {
console.log(e.target.result); // данные файла в виде строки
};
reader.readAsText(file); // чтение как текст
}
Методы чтения файлов:
readAsText(file) — текстовый формат.readAsDataURL(file) — для изображений и файлов,
возвращает base64.readAsArrayBuffer(file) — бинарные данные.readAsBinaryString(file) — устаревший, лучше
использовать ArrayBuffer.Vue позволяет связывать выбранные файлы с данными компонента через реактивное состояние:
data() {
return {
uploadedFiles: []
};
},
methods: {
handleFileUpload(event) {
this.uploadedFiles = Array.from(event.target.files);
}
}
Array.from преобразует FileList в обычный
массив, удобный для отображения и обработки в шаблоне.
<ul>
<li v-for="file in uploadedFiles" :key="file.name">
{{ file.name }} ({{ file.size }} байт)
</li>
</ul>
Для отправки файлов на сервер чаще всего используется
FormData:
uploadFiles() {
const formData = new FormData();
this.uploadedFiles.forEach(file => {
formData.append('files[]', file);
});
fetch('/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log('Успех:', data);
})
.catch(error => {
console.error('Ошибка:', error);
});
}
Особенности FormData:
Content-Type как
multipart/form-data.Для отображения изображений до отправки на сервер используется
FileReader.readAsDataURL:
previewImage(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onl oad = (e) => {
this.imagePreview = e.target.result;
};
reader.readAsDataURL(file);
}
Шаблон для превью:
<img v-if="imagePreview" :src="imagePreview" alt="Preview" />
Реактивное свойство imagePreview обновляется
автоматически, и картинка появляется сразу после выбора файла.
Для предотвращения загрузки больших файлов или неподходящих форматов используются проверки:
handleFileUpload(event) {
const files = Array.from(event.target.files);
this.uploadedFiles = files.filter(file => {
const isValidType = ['image/jpeg', 'image/png'].includes(file.type);
const isValidSize = file.size <= 2 * 1024 * 1024; // 2 МБ
return isValidType && isValidSize;
});
}
Это позволяет отказаться от файлов, не соответствующих требованиям, ещё на клиенте.
Для обработки больших файлов рекомендуется использовать асинхронные
функции и Promise:
async processFiles(files) {
for (const file of files) {
const content = await this.readFileAsync(file);
console.log(content);
}
},
readFileAsync(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onl oad = () => resolve(reader.result);
reader.oner ror = reject;
reader.readAsText(file);
});
}
Это обеспечивает последовательное чтение файлов без блокировки
основного потока и совместимо с современными подходами работы с
async/await.
Vue легко интегрируется с библиотеками для работы с файлами:
FormData на
сервер.Библиотеки позволяют ускорить разработку и расширяют функциональность без написания большого объёма кода.
Поддержка перетаскивания файлов реализуется через события
dragover и drop:
<div
@dragover.prevent
@drop.prevent="handleDrop"
class="drop-zone">
Перетащите файлы сюда
</div>
Метод обработки:
handleDrop(event) {
const files = Array.from(event.dataTransfer.files);
this.uploadedFiles = files;
}
Событие preventDefault необходимо, чтобы браузер не
открывал файл по умолчанию.