[Vue] multiple input file을 이용한 파일 부분 삭제 구현

2022. 7. 29. 10:38Vue

<div class="col-12" >
  <div class="form-group">
    <p class="label_head" >첨부파일</p>
    <div id="customFile" class="custom-file">
      <input type="file" 
              class="file" 
              name="file" 
              ref="uploadFile" 
              @change="previewFiles" 
              multiple>
    </div>
    <div v-for="(item, idx) in fileName">
      <span>{{ item }}</span>
    <button type="button" @click="deleteFile(idx)" class="btn">X</button>
    </div>
  </div>
</div>

<script>
import ax from '@/api/qna'

export default {
  name: 'QnaWrite',
  data() {
    return {
      file: [],
      fileName: [],
      dataTransfer: []
    }
  },
  methods: {
    resetForm() {
      this.form = _.cloneDeep(this.form_)
    },
    deleteFile(idx) {
      this.fileName.splice(idx, 1)

      this.dataTransfer = new DataTransfer()
      
      let files = document.querySelectorAll('.file')[0].files
      let fileArray = Array.from(files)
      
      fileArray.splice(idx, 1)
      fileArray.forEach(element =>  {
        this.dataTransfer.items.add(element)
      })

      files = this.dataTransfer.files
    },
    previewFiles(event) {
      let selectFile = event.target.files

      if ((this.fileName.length + selectFile.length) > 5) {
        alert('파일갯수는 최대 5개입니다.')
        document.querySelector('.file').value = ""
        return
      }

      selectFile.forEach(i => {
        this.fileName.push(i.name)
        this.file.push(i)
      })

    },
    insertMemberBoard() {
      let form = new FormData();

      // 사진 삭제 하지 않고 등록할 때
      if (this.dataTransfer.files === undefined) {
        if (this.file) {
          for (let i = 0; i < this.file.length; i++) {
            form.append("file", this.file[i])
          }
        }
      } else if (this.file) {
        // 사진 삭제하고 등록할 때
        this.file = this.dataTransfer.files
        for (let i = 0; i < this.file.length; i++) {
          form.append("file", this.file[i])
        }
      }

      ax.insert(form, (response) => {
        alert("게시글이 등록되었습니다")
        this.$router.push({ path: '/qna', query: this.$route.query })
      })
    }
  }
}
</script>

 

 

1. 파일업로드 경우의 수

  • 1. 파일을 선택X
  • 2. 파일을 선택O 삭제X 
  • 3. 파일을 선택O 삭제O

 

1번의 경우 파일을 선택하지 않았으므로, formData로 값을 전달해 줄 필요가 없다.

2번의 경우 파일을 삭제 하지 않았을 때 undefined로 판단해주어서, if문 안으로 들어오게 하였다.

this.dataTransfer.files === undefined

3번의 경우 this.file은 <input="file" multiple> 로 담긴 파일배열이고,

this.dataTransfer은 삭제한 파일이 있을 때, this.file로 다시 할당시켜준다. (dataTransfer가 비교의 대상이 되는셈)

 

 

2. DataTransfer

DataTransfer개체는 드래그 앤 드롭 작업 중에 드래그되는 데이터를 유지하는 데 사용된다 . 

각각 하나 이상의 데이터 유형인 하나 이상의 데이터 항목을 선택할 수 있다.

 

이 코드가 많은 도움이 되었다.

const delete = (fileNum) => {	//fileNum은 li 의 index 값
    const dataTransfer = new DataTransfer();
    
    let files = $('#file')[0].files;	//사용자가 입력한 파일을 변수에 할당
    
    let fileArray = Array.from(files);	//변수에 할당된 파일을 배열로 변환(FileList -> Array)
    
    fileArray.splice(fileNum, 1);	//해당하는 index의 파일을 배열에서 제거
    
    fileArray.forEach(file => { dataTransfer.items.add(file); });
    //남은 배열을 dataTransfer로 처리(Array -> FileList)
    
    $('#file')[0].files = dataTransfer.files;	//제거 처리된 FileList를 돌려줌
}
deleteFile(idx) {
  this.fileName.splice(idx, 1)

  this.dataTransfer = new DataTransfer()
  
  let files = document.querySelectorAll('.file')[0].files
  let fileArray = Array.from(files)
  fileArray.splice(idx, 1)

  fileArray.forEach(element =>  {
    this.dataTransfer.items.add(element)
  })

  files = this.dataTransfer.files
}

 

 

 

 

 

 

DataTransfer - Web API | MDN

The DataTransfer object is used to hold the data that is being dragged during a drag and drop operation. It may hold one or more data items, each of one or more data types. For more information about drag and drop, see HTML Drag and Drop API.

developer.mozilla.org

 

[Spring / Legacy] multiple input file을 이용한 파일 전체/부분 삭제 구현 (Javascript)

Spring Legacy 프로젝트를 진행하는 도중, 여러 개의 파일을 한번 에 추가해야 할 일이 있었다. 여러 개의 Single 파일을 한 줄씩 입력하게 하면 편했겠지만, 많은 파일을 한 번에 올릴 확률이 더 크기

devlifetestcase.tistory.com

 

'Vue' 카테고리의 다른 글

[vue] 컴포넌트에서 watch() 사용하여 router 이동 감지하기  (0) 2022.09.14
[Vue] router  (0) 2022.09.14
[Vue] router 의 meta  (0) 2022.07.12
$nextTick  (0) 2022.07.04
$set / $delete  (0) 2022.07.04