본문 바로가기
개발이야기/Vuetify

[Vuetify] 다중 업로드 모달창 만들기

by dev.josh 2020. 1. 18.
반응형

환경

- Node v10.16.0

- Vuetify2

 

결과물

 

 

Vuetify의 Dialog와  vue-upload-component 라이브러리를 활용해서 다중 업로드 모달창을 만들어 봤다.

 

(※개인적으로 팝업/모달 이라고 부르는데 뷰티파이에서는 다이얼로그 라고 표현하여 본 게시물에서는 Dialog로 통일하겠다.)

 

 

1. Page.vue - Dialog를 열기위한 버튼영역

    <v-container fluid class="pa-0">
      <v-row align="center">
        <v-col cols="12" sm="12" md="12">
          <div class="text-center">
            <div class="my-2">
              <v-btn @click="openDialog()" large color="blue" dark>
                <v-icon class="mr-2">cloud_upload</v-icon>
                Upload
              </v-btn>
            </div>
          </div>
        </v-col>
      </v-row>
    </v-container>

 

 

2. Page.vue - Dialog 영역

    <v-dialog v-model="dialog" persistent max-width="900px">
      <v-card>
        <v-card-title>
          <template>
            <v-icon style="margin-right:10px;" large color="#41B883" >cloud_upload</v-icon> 
            <span class="headline" large>파일 업로드</span>
          </template>
          <v-spacer></v-spacer>
          <v-btn icon @click="closeDialog()"> 
            <v-icon>clear</v-icon>
          </v-btn>
        </v-card-title>
        <v-card-text>
          <v-row>
            <v-col cols="12" sm="12" md="12" style="position: relative; border:1px solid #41B883; border-style:dashed; ">
              <Upload></Upload> 
            </v-col>
          </v-row>
        </v-card-text>
      </v-card>
    </v-dialog>

 

3. Page.vue - Script 영역

import Upload from "./Upload.vue";

export default {
  components: {
    Upload
  },
  data: ()=> ({
    dialog: false, //true : Dialog열림, false : Dialog닫힘
  }),
  methods: {
    openDialog() { //Dialog 열리는 동작
      this.dialog = true;
    },
    closeDialog() { //Dialog 닫히는 동작
      this.dialog = false;
    },
  }
}

 

 

4. Upload.vue

  <div class="example-drag">
  	<!-- 파일을 드래그할때 노출되는 영역 --> 
    <div v-show="$refs.upload && $refs.upload.dropActive" class="drop-active"> 
      <h3>Drop files to upload</h3>
    </div>
    <!-- 파일이 1개이상 존재하는 경우 -->
    <template v-if="files.length"> 
      <!-- 파일 목록 -->
      <v-data-table 
        dense 
        :headers="headers" 
        :items="files" 
        item-key="name" 
        class="elevation-1"
        hide-default-footer
      > 
      </v-data-table>
      <!-- 파일 업로드 처리 실행 버튼 -->
      <v-btn
        class="ma-2"
        style="padding:0px;"
        color="info"
        @click="uploadStart()"
      > 
        <v-icon style="margin-right:5px;">arrow_upward</v-icon>UpLoad Start
      </v-btn>
    </template>
    <!-- 파일이 없을때 -->
    <template v-else> 
    <!-- vue-upload-component 라이브러리 영역 --> 
    <!-- onDrop 파일업로드 직후 동작 -->
      <FileUpload
        class="btn btn-primary"
        :multiple="true"
        :drop="true"
        :drop-directory="true"
        v-model="files"
        ref="upload"
        @input="onDrop($event)" 
      > 
      </FileUpload> 
      <v-row>
        <v-col cols="12" sm="12" md="12">
          <div class="text-center p-5">
            <h4>Drop files anywhere to upload<br/>or</h4>
            <!-- 파일 업로드 버튼 영역 -->
              <v-btn
                class="ma-2"
                style="padding:0px;"
                color="info"
              > 
                <label for="file" style="padding:0px 8px;"><v-icon style="margin-right:5px;">add_circle</v-icon>Select Files</label>
              </v-btn>
          </div>
        </v-col>
      </v-row>
    </template>
  </div>

 

4. Upload.vue  Script 영역

import FileUpload from "vue-upload-component";

export default {
  components: {
    FileUpload
  },
  data: ()=> ({
    files: [], //파일 변수
    headers: [ //파일 업로드 후 테이블 영역 헤더부분
      { text: 'name', value: 'name' },
      { text: 'size', value: 'size' },
    ],
  }),
  methods: {
    onDrop(item){ //파일업로드 직후 동작
      console.log(item)
    },
    uploadStart(){
      //업로드 처리로직
    }
  },
}

 

5. Upload.vue CSS 영역

.example-drag .drop-active {
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  position: fixed;
  z-index: 9999;
  opacity: .6;
  text-align: center;
  width:100%;
  background: #000;
}
.example-drag .drop-active h3 {
  margin: -.5em 0 0;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
  font-size: 40px;
  color: #fff;
  padding: 0;
}

 

 

 

vue-upload-component의 스타일 부분이 뷰티파이와 함께 썻을때 충돌이 난다.

때문에 4. Upload.vue 컴포넌트를 만들어서 시작 엘리먼트를 뷰티파이로 쓰지 않았을때 정상으로 스타일이 나왔다.

 

여기까지 다중업로드 화면단만 제작해 보았고 추후에 서버와 함께 업로드 되는 부분을 진행해보도록 하겠다.

 

완성된 소스는 https://github.com/Jo-App/vuetify_upload 에서 확인 가능합니다.

 

 

참고자료

https://vuetifyjs.com/en/components/dialogs#dialogs

 

Dialog component — Vuetify.js

The dialog component informs a user about a specific task and may contain critical information or require the user to take a specific action.

vuetifyjs.com

 

전체소스

https://github.com/Jo-App/vuetify_upload

 

Jo-App/vuetify_upload

Contribute to Jo-App/vuetify_upload development by creating an account on GitHub.

github.com

 

반응형