#html #image #vue.js #vue-component
#HTML #изображение #vue.js #vue-компонент
Вопрос:
Я пытаюсь отобразить предварительный просмотр некоторых изображений, когда пользователь выбирает их перед их загрузкой, но я новичок в vue и не могу понять, как применить стиль URL-адреса фонового изображения к каждому div (он должен быть с фоновым изображением), вот мой UploadComponent до сих пор:
<template>
<div class="content">
<h1>{{ title }}</h1>
<div class="btn-container">
<label class="button" for="images">Select Images</label>
<input type="file" id="images" name="images[]" multiple="multiple" @change="selectFiles"/>
</div>
<br><br>
<div class="block">
<h3>Selected images</h3>
<div v-for="image in images" v-bind:key="image" class="image-result" v-bind:style="{ backgroundImage: 'url(' image ')' }">
</div>
</div>
<div class="btn-container">
<button type="button" class="submit-btn" v-on:click="uploadImages">Submit Images</button>
</div>
<br><br>
<div class="block">
<h3>Uploaded images</h3>
<div class="files-preview">
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'UploadComponent',
data: () => ({
title: 'Select your images first and then, submit them.',
images: []
}),
methods:{
selectFiles(event){
var selectedFiles = event.target.files;
var i = 0;
for (i = 0; i < selectedFiles.length; i ){
this.images.push(selectedFiles[i]);
}
for (i = 0; i < this.images.length; i ){
let reader = new FileReader(); //instantiate a new file reader
reader.addEventListener('load', function(){
console.log(this);
}.bind(this), false); //add event listener
reader.readAsDataURL(this.images[i]);
}
},
uploadImages(){
const data = new FormData();
data.append('photos', this.images);
axios.post('url')
.then(res => {
console.log(res);
});
}
}
}
</script>
Создаются divs, но мне не хватает той части, где я назначаю фоновое изображение, как я могу это решить?
Ответ №1:
Вы не можете просто поставить a File
непосредственно в качестве параметра для background-image
. Вы начали использовать FileReader
, но ничего не сделали с результатом.
Вот что я хотел бы сделать ниже, я преобразовал ваш images
массив в список объектов, у которых есть file
свойство и preview
свойство, просто чтобы сохранить файл и предварительный просмотр связанными вместе.
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: "#app",
data: () => {
return {
title: 'Select your images first and then, submit them.',
images: []
}
},
methods: {
selectFiles(event) {
var selectedFiles = event.target.files;
for (var i = 0; i < selectedFiles.length; i ) {
let img = {
file: selectedFiles[i],
preview: null
};
let reader = new FileReader();
reader.addEventListener('load', () => {
img.preview = reader.result;
this.images.push(img);
});
reader.readAsDataURL(selectedFiles[i]);
}
},
uploadImages() {
const data = new FormData();
data.append('photos', this.images.map(image => image.file));
axios.post('url')
.then(res => {
console.log(res);
});
}
}
});
.image-result {
width: 100px;
height: 100px;
background-size: contain;
background-repeat: no-repeat;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="content">
<h1>{{ title }}</h1>
<div class="btn-container">
<label class="button" for="images">Select Images</label>
<input type="file" id="images" name="images[]" multiple="multiple" @change="selectFiles" />
</div>
<br><br>
<div class="block">
<h3>Selected images</h3>
<div id="target-photos">
</div>
<div v-for="image in images" class="image-result" v-bind:style="{ backgroundImage: 'url(' image.preview ')' }">
</div>
</div>
<div class="btn-container">
<button type="button" class="submit-btn" v-on:click="uploadImages">Submit Images</button>
</div>
<br><br>
<div class="block">
<h3>Uploaded images</h3>
<div class="files-preview">
</div>
</div>
</div>