이것저것 코딩공부/Vue

[Vue3] 이미지 프리뷰 (1개/여러개) 간단하게 만들기

김쨔뿌 2022. 6. 2. 14:17

핵심

  • event.target.files 
  • URL.createObjectURL

 

프리뷰 만드는 방식이 어려울거라 여겼는데 생각보다 쉬워서 깜놀했땃쥐..

굳이 vue 말고 다른 프레임워크에서도 비슷한 방식으로 하면 됨 

 

  1. input의 onchange 이벤트에서 event.target.files 로 파일객체들이 들어간 객체를 불러와주고
  2. URL.createObjectURL(파일객체) 로 파일객체를 src에 넣을 주소로 바꿔준 뒤
  3. img 태그의 src 를 업데이트 시켜주면 끝! 

 

아래는 vue3 기준 script setup 쓸 때의 코드 + typescript

1개만 불러올 때

<!-- <template> -->

 <input type="file" @change="addImage" />
 <img :src="src" />
// <script setup lang="ts">
import { ref } from 'vue';

const src = ref();

const addImage = (e: Event) => {
  const [file] = (e.target as HTMLInputElement).files;
  console.log((e.target as HTMLInputElement).files);
  if (file) {
    src.value = URL.createObjectURL(file);
  }
};

*타입스크립트 안쓰면 addImage에서 as HTMLInputElement 를 지워주면 된다. 

const addImage = (e: Event) => {
  const [file] = e.target.files;
  console.log(e.target.files);
  if (file) {
    src.value = URL.createObjectURL(file);
  }
};

이러면 onchange 이벤트 발생시 src가 변경되고 콘솔에 이런 식으로 파일이 찍힌다 ㅇㅇ

FileList 라는 객체 안에 Index 키값을 가진 File객체가 나옴! 저게 URL.createObjectURL 로 들어가서 주소로 바꿔주는 거쉬댜~

 

여러개 불러올 때

위랑 달라진 부분만 적어보자면.. input에 multiple이 추가되고 addImage 함수에 반복문 추가!

<input type="file" @change="addImage" multiple />
<img v-for="(item, index) in src" :key="index" :src="item" />
const src = ref([]);

const addImage = (e: Event) => {
  const file = (e.target as HTMLInputElement).files;
  const fileLength = file.length;
  let newList = [];
  for (let i = 0; i < fileLength; i++) {
    newList.push(URL.createObjectURL(file[i]));
  }
  src.value = newList;
};

여기서 저 file.length로 반복문 쓰지 말고 for in 써두 되지 않을까? 해서 써봤는데 에러 뜸... 

원인은 아직도 모르겠다. 구글링을 해보니 createObjectURL에 파일객체가 안들어가서 그럴 수 있다던데 콘솔로그로 찍으면 파일객체로 떠서 흠..? 

 

input 태그에 multiple을 사용하면 이미지를 여러개 선택할 수 있다. 선택된 n개의 이미지들에 대한 File객체는 1개만 불러올때와 같이 Filelist 객체 안에 index를 key값으로 가진다... 이걸 이용해서 루프 돌리면 끝!

 

 

참고

https://stackoverflow.com/questions/4459379/preview-an-image-before-it-is-uploaded

 

Preview an image before it is uploaded

I want to be able to preview a file (image) before it is uploaded. The preview action should be executed all in the browser without using Ajax to upload the image. How can I do this?

stackoverflow.com