익명의 개발노트

[vue.js] How to preview multiple images before upload? 본문

코딩일기/TIL

[vue.js] How to preview multiple images before upload?

캡틴.JS 2020. 4. 22. 20:15
반응형

 

업로드 사진

input 태그를 이용하여 여러개의 파일을 선택하여, 업로드 전 미리보기를 구현하려 한다.

한 개씩 적용할 때는 간단했는데, 여러개를 동시에 보여주려고 하니, 문제가 발생했다.

<input type="file" 
       :id="'uploadFile'+index" 
       ref="uploadThumbFile"
       @change="onFileSelected"
       accept="image/*"
       multiple
       />

아래 코드는 한개씩 클릭해서 올리는 방식일때 코드이며, this.uploadImages는 컴포넌트의 자체 state 값(data() 안에 값)이다.

onFileSelected(event){
    var input = event.target; 
    if (input.files && input.files[0]) { 
        var reader = new FileReader(); 
        reader.onload = (e) => { 
        this.uploadImages.push(e.target.result);      
     }; 
     reader.readAsDataURL(input.files[0]); 
     event.target.value =''; // 있어야 같은 파일 지웠다가 다시 올릴수 있음.
}

여러개를 동시에 올려서 보일때는 위 코드와 차이점이 reader.onload 부분이 차이가 있다.

실제로 작성해보면 reader.onload 부분에서 맨처음 클릭한 이미지 버퍼값만 가져오고, 나머지는 가져오지 못한다.

구글링 해본결과 비동기 문제 인 것 같아서(혹시나 틀린정보라면 댓글 부탁드립니다), Promise.all을 이용하여 해결했다.

1. addEventListener을 이용한 방법

if (e.target.files) { 
   const files = Array.from(e.target.files);
 
    Promise.all(files.map(file => {
      return (new Promise((resolve, reject) =>{
      
         let reader = new FileReader(); 
         
         reader.addEventListener('load', ev => {
           resolve(ev.target.result);
         });
    
         reader.addEventListener('error', reject);
         reader.readAsDataURL(file);
      }));
    }))
    .then(images => {
        this.uploadImages = images; //state 값에 저장
     }, error => {
         console.error(error);
     });
 }

2. on 이벤트을 이용한 방법

if (e.target.files) { 
   const files = Array.from(e.target.files);
 
    Promise.all(files.map(file => {
      return (new Promise((resolve, reject) =>{
      
         let reader = new FileReader(); 
         
         reader.onload = ev => {
           resolve(ev.target.result);
         };
    
         reader.onerror = () => {
         	reject()
         };
         reader.readAsDataURL(file);
      }));
    }))
    .then(images => {
        this.uploadImages = images; //state 값에 저장
     }, error => {
         console.error(error);
     });
 }
 
 

코드 스타일은 알아서 선택하면 될 듯 싶다.

반응형
Comments