개발자
<template> <div> <input ref="fileInput" type="file" accept="image/*" multiple="true" @change="handleFileInputChange" /> <button @click="openFileInput" class="select-button"> Select Images </button> <div class="preview-container"> <div v-for="file in selectedFiles" :key="file.lastModified" class="preview-item" > <p>{{ file.name }}</p> <div class="preview"> <img :src="previewImage" style="width: 100px" /> </div> <!-- <img :src="URL.createObjectURL(file)" /> --> <button @click="removeFile(file.lastModified)" class="remove-button"> X </button> </div> </div> </div> </template> <script setup lang=“ts”> const fileInput = ref() const selectedFiles: Ref<Array<any>> = ref([]) const openFileInput = () => { fileInput.value.click() } const previewImage = ref<any>('') const handleFileInputChange = e => { // const files = Array.from(fileInput.value.files) const files = e.target.files console.log('files', files) selectedFiles.value.push(...files) console.log('add selectedFiles', selectedFiles.value) for (let i = 0; i < selectedFiles.value.length; i++) { const file = selectedFiles.value[i] console.log('handleFileInputChange_ file', selectedFiles.value[i]) const reader = new FileReader() reader.onload = e => { previewImage.value = e.target.result } reader.readAsDataURL(file) } } const removeFile = lastModified => { selectedFiles.value = selectedFiles.value.filter( file => file.lastModified !== lastModified ) console.log('remove selectedFiles', selectedFiles.value) } </script> 모바일에서 카메라로 찍은 여러장의 사진들이 각각의 썸네일로 노출되어야함 현재는 최신 사진으로 엎어치기 됨.. 예) 'A B C D' 의 사진이 나와야하는데 현재는 A 찍고 B찍으면 'B B' 가 됨 C찍으면 'C C C'가 됨 도와주세요!
답변 3
해당 반복문에서 previewImage에 마지막 이미지 값을 덮어 씌워서 그런 것 같은데요? files 순회하면서 selectedFiles에 이미지 파일이랑 preview data를 같이 넣으면 어떨까 싶습니다. 이미지 관련해서 readAsDataURL 사용하고 계시는데 createObjectURL랑 비교해둔 글 있는데 참고하시면 좋을 것 같습니다. https://www.andygup.net/performance-comparison-between-readasdataurl-and-createobjecturl/
1for (let i = 0; i < selectedFiles.value.length; i++) {
2 const file = selectedFiles.value[i]
3 console.log('handleFileInputChange_ file', selectedFiles.value[i])
4 const reader = new FileReader()
5 reader.onload = e => {
6 previewImage.value = e.target.result // 이 부분
7 }
8 reader.readAsDataURL(file)
9 }
10}
문제의 원인은 'previewImage' 변수가 모든 썸네일에 대해 공통으로 사용되고 있기 때문입니다. 따라서 썸네일을 생성할 때마다 'previewImage' 값을 업데이트하면 이전에 생성된 썸네일에도 영향을 주게 됩니다. 해결 방법은 각각의 사진에 대한 'previewImage' 값을 개별적으로 관리하는 것입니다. 아래는 수정된 코드입니다: 아래의 코드에서 'getPreviewImage' 함수는 각각의 사진에 대한 'previewImage' 값을 리턴하도록 변경되었습니다. 각각의 사진은 개별적으로 'previewImage' 값을 가지게 되며, 'getPreviewImage' 함수는 해당 사진에 대한 'previewImage' 값을 업데이트하고 리턴합니다. 또한 'removeFile' 함수에서 선택한 사진을 'selectedFiles' 배열에서 삭제하는 방식으로 수정되었습니다. 이렇게 수정하면 각각의 사진에 대해 개별적인 썸네일이 표시되며, 최신 사진으로 엎어치는 문제가 해결될 것입니다.
1<template>
2 <div>
3 <input
4 ref="fileInput"
5 type="file"
6 accept="image/*"
7 multiple="true"
8 @change="handleFileInputChange"
9 />
10 <button @click="openFileInput" class="select-button">
11 Select Images
12 </button>
13 <div class="preview-container">
14 <div
15 v-for="(file, index) in selectedFiles"
16 :key="file.lastModified"
17 class="preview-item"
18 >
19 <p>{{ file.name }}</p>
20 <div class="preview">
21 <img :src="getPreviewImage(file)" style="width: 100px" />
22 </div>
23 <button @click="removeFile(index)" class="remove-button">
24 X
25 </button>
26 </div>
27 </div>
28 </div>
29</template>
30
31<script setup lang="ts">
32import { ref } from 'vue'
33
34const fileInput = ref()
35const selectedFiles = ref([])
36
37const openFileInput = () => {
38 fileInput.value.click()
39}
40
41const getPreviewImage = (file) => {
42 const reader = new FileReader()
43 const image = ref('')
44
45 reader.onload = (e) => {
46 image.value = e.target.result
47 }
48 reader.readAsDataURL(file)
49
50 return image
51}
52
53const handleFileInputChange = (e) => {
54 const files = e.target.files
55 selectedFiles.value.push(...files)
56}
57
58const removeFile = (index) => {
59 selectedFiles.value.splice(index, 1)
60}
61</script>
커리어리 AI 봇의 답변을 평가해 주세요!
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!