vue
<label id="btn-file-label" v-bind:for="profile.id">
<button class="btn-file px-2 ml-2" >
<img src='file.jpg' > 파일첨부
</button>
</label>
<input accept="image/*" v-bind:id="profile.id" style="display: none;" type="file"
v-on:change="myFileUpload" multiple>
<!-- for문으로 첨부된 파일들을 표시 -->
<div v-for="(file, index) in myFiles" v-bind:key="file.id" class="files-name">
<span class="btn-cancel" @click="btnDeleteClick(file.id, file.file_name, file.user_id, file.user_name)"> [파일 삭제]</span>
<span><a :href="file.file_url" target="_blank">{{file.file_name}}</a></span>
</div>
1. 실제 파일업로드 input 은 display:none으로 숨기고,
2. 커스텀 button 에 label을 씌워서 '파일첨부' 텍스트 클릭 시 파일업로드 창이 뜨게 구현
script
<script>
export default {
data() {
return {
myFiles: null
}
},
methods: {
myFileUpload(e) {
e.preventDefault();
const config = {
headers : {'content-type': 'multipart/form-data'}
};
const formData = new FormData();
e.target.files.forEach(function(item) {
formData.append('my_files[]', item);
});
//param.settings
formData.append('user_id', this.profile.user_id);
formData.append('user_name', this.profile.user_name);
axios.post('/profile/upload', formData, config)
.then((response) => {
if(response.data.code == 404) { // laravel 에서 리턴해주는 custom helper
console.log(`${response.data.error}`); // custom error message
} else {
this.myFiles = response.data; // return 된 값을 받아서 for문 업데이트
}
});
},
}
}
</script>
1. myFiles 라는 변수를 생성해놓고,
2. http 요청을 할 header와 formdata 들을 세팅
3. 업로드가 끝난 후 v-for 에 사용되는 myFiles 를 업데이트
laravel
route :
Route::post('/profile/upload', 'UserController@myFileUpload');
controller :
실제 구현시에 로직은 service로 빼는것이 유지보수에 좋지만,
지금은 흐름만 적는 것이므로 controller에서 처리
<?php
public function myFileUpload(Request $request)
{
if (Auth::check() && $request->hasFile('family_files')) { // 로그인과 파일이 있는지 체크
$user = Auth::user();
$rootPath = 'user_files'; // S3 에서의 파일 저장 경로
foreach ($request->file('myFiles') as $file) {
// 파일 업로드
$userFile = new UserFile;
$userFile->user_id = $request->user_id;
$userFile->user_name = $request->user_name;
// 파일 클릭시 원본 이미지 표시를 위해 리사이즈 세팅
$width=600;
$extension = $file->getClientOriginalExtension();
$uniqid = uniqid();
$filename = $uniqid. '_' . time() . '.' . $extension;
$filepath = $rootPath . '/' . $filename;
$image = Image::make($file);
$image->width() > $width ? $width : $width=$image->width();
$image->resize($width, null, function($constraint){
$constraint->aspectRatio();
})->encode($extension);
// S3에 파일 저장
Storage::cloud()->put($filepath, (string)$image);
// 파일 경로를 DB에 저장
$userFile->file_name = $file->getClientOriginalName();
$userFile->file_url = Storage::cloud()->url($filepath);
$userFile->save();
}
// 해당 유저의 파일들을 DB에서 모두 가져옴
$userFiles = $this->getFiles($request);
if ($userFiles->isEmpty()) {
return errorCode(404, '파일이 없습니다.'); // custom helper 함수
}
$response = $userFiles;
} else {
return errorCode(404, '첨부파일 업로드 실패');
}
return $response;
}
1. http 요청으로 넘어온 데이터들을 S3로 저장 및 DB에 저장하고
2. 유저의 파일들을 모두 다시 가져온 뒤 리턴
반응형
'Vue.js' 카테고리의 다른 글
[Vue.js] vue 파일 변경 시 자동 컴파일 하는 법 (0) | 2021.09.09 |
---|---|
[Vue.js] 뷰에서 사용할 수 있는 alert 컴포넌트 (0) | 2021.09.08 |
[Vue.js] 컴포넌트 연동하기 (0) | 2021.04.23 |
[Vue.js] Vue에서 isMobile 모바일 구분 사용하기 (0) | 2021.04.19 |
[Vue.js] Vue에 Google Adsense 넣기 (0) | 2021.04.15 |