반응형
upload.html
<div id="app">
<!-- 첨부파일 영역 예시 -->
<div class="field-head">
첨부파일<span class="text-red"></span>
<span id="extensions" class="text-red">[.jpg, .jpeg, .png, .xlsx, .hwp, .docx, .pptx, .pdf]</span>
<div class="util-box">
<!-- 파일 배열이 5개보다 크면 비활성화 --> <!-- @click.prevent로 a태그의 기본값을 막는다. -->
<a href="#" :disabled="files.length >= 5" @click.prevent="addAttachFile"><span class="material-icons">add</span></a>
<a href="#" @click.prevent="removeAttachFile"><span class="material-icons">remove</span></a>
</div>
</div>
<div class="field-box" id="fileBox">
<!-- hasAttachment가 false일 때만 표시된다. -->
<div class="a_c bg-light" v-show="!hasAttachment"> <br>
확장자는 .jpg, .jpeg, .png, .xlsx, .hwp, .docx, .pptx, .pdf 만 가능합니다. <br>
5MB이하 파일만 올려주세요.
</div>
<!-- 여기가 핵심 -->
<ul classname="file-list">
<!-- Vue.js의 인스턴스의 files 크기만큼 루프 -->
<li v-for="(item, index) in files" :key="index">
<div class="flex-box frm-file mt05">
<span>{{ item.num }}</span><span class="mr5">.첨부</span>
<!-- file1, file2, file3 이런식으로 세팅하기 위함이다. -->
<input type="text" ref="'file' + item.num" title="" class="input-default file-txt">
<input type="file"
:id="'filefrm' + item.num"
ref="'filefrm' + item.num"
class="btn-file"
title="파일찾기"
accept=".jpg, .jpeg, .png, .xlsx, .hwp, .docx, .pptx, .pdf"
<!-- 체인지 이벤트 핸들러 연결 -->
@change="handleFileChange($event, index)"
>
<label :for="'filefrm' + item.num">파일 첨부</label>
</div>
</li>
</ul>
</div>
</div>
<button type="button" @click="reg" class="btn btn-normal">저장</button>
<script>
// 기존 코드를 편집해서 {} 열고 닫는게 안 맞을 수도 있음
new Vue({
//element id
el: '#app',
//vue에서 관리할 데이터
data: { files: [], //첨부파일
hasAttachment: false, // flag 용도
},
methods: {
/**
* 등록
*/
reg() {
const self = this; // 인스턴스 참조 변수
if (confirm("등록을 하시겠습니까?")) {
//formdata 새로운 객체 생성
const formData = new FormData();
//첨부파일 세팅
for (const fileData of this.files) {
if (fileData.file) {
formData.append('files', fileData.file);
}
}
const url = '/api/file';
//post http request
axios.post(url, formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
.then(function(response) {
console.log(response.data.code);
if(response.data.code === '1') {
alert("등록되었습니다.");
location.href = "/";
} else {
alert("등록에 실패 했습니다.");
}
}.bind(this))
.catch(function(error) {
alert("등록에 실패 했습니다.");
console.log(error);
});
}
}
},
/**
* 첨부파일 영역 추가
*/
addAttachFile() {
if(this.files.length >= 5) {
alert("첨부파일은 5개까지 등록 가능합니다");
return false;
}
this.files.push({ name: `Files ${this.files.length + 1}`, file: null, num: this.files.length + 1});
this.hasAttachment = true;
},
/**
* 첨부파일 영역 삭제
*/
removeAttachFile() {
if (this.files.length > 0) {
this.files.pop();
}
if (this.files.length === 0) {
this.hasAttachment = false;
}
},
/**
* 선택된 첨부파일 세팅
* @param event
* @param index
*/
handleFileChange(event, index) {
const selectedFile = event.target.files[0];
this.files[index].file = selectedFile;
},
});
</script>
위 코드는 동적으로 첨부파일 영역을 추가/삭제 후 첨부파일을 업로드 하는 간단한 예제이다.
전체적으로 포스팅을 위해 편집한 코드라서 태그 열고 닫고 안 맞을 수도 있다.
첨부파일 관련 메소드는 총 4개이다.
첨부파일 데이터를 담을 배열이 인스턴스의 data 객체안에 초기화 된 상태이고
addAttachFile(), removeAttachFile()로 data 객체의 files 배열의 값을 추가/삭제 한다.
배열에 값을 추가/삭제 후 화면에 연결해주면 Vue.js에서 데이터 변경감지를 해서 알아서 표시해준다.
추가 시 배열에 name, file, num을 추가한다.
첨부파일 영역에서는 동적으로 설정되는 files배열의 크기만큼 루프를 돌아서 화면에 렌더링 되고
첨부파일 추가 시 handleFileChange() 메소드를 통해서 파일을 files 배열에 세팅 후
서버 전송 시 첨부파일 리스트만큼 formData에 세팅 후 multipart/form-data 타입으로 보내고
결과코드에 따라 분기처리한다.
반응형
'IT > development' 카테고리의 다른 글
[springBoot] daum SMTP 메일 발송 (43) | 2023.08.22 |
---|---|
[github] github 웹 vs code 사용 (0) | 2023.08.17 |
[JavaScript] 템플릿 문자열 사용법(feat. '(백틱)) (2) | 2023.08.13 |
[JavaScript] 자식 팝업창에서 부모창의 함수 호출(javascript 위주) (0) | 2023.08.13 |
[springBoot] 서로 다른 branch를 동시에 띄우려면? (0) | 2023.08.12 |