실무/vue.js 실무 기능

11. vue로 Modal창, Modal Drag 구현 | v-for, v-if

DEV-Front 2023. 1. 15. 18:34
반응형
<template>
  <div class="notice--bg"v-if="noticeList > 0">
    <div class="notice" v-for="(item, i) in modalList" :key="i"
    	@mousedown="dragMouseDown(i)">
        
        <div :class="[`subject drag${i}`]" style="position : absolute;">
         {{ item.subject }}
        </div>
        <div class="content" v-html="item.content"></div>
        
     </div>
   </div>
</template>

<script>
let zIndex = 9100;
let top;
let left;
 
export default {
  data() {
    return {
      modalList : [],
      noticeNum: 0,
      noticeList: 0,
      
      positions : {
          clientX,
          clientY,
          movementX,
          movementY,
      }
    };
  },
  methods: {
     async getAllNotce(){
      await axios.post(`api/notice`)
      	.then(data => {
         for(let i; i<data.length; i++){
        temp = {};
           temp.subject = data.subject;
           temp.contents = data.contents;
           temp.module = data.module;
            
            this.modalList.push(temp); 

		/* 공지사항 여러개일때 맨 위 공지사항 클릭되도록
              noticeNum에 공지사항중 제일 마지막 값 넣어놓음 */
            this.noticeNum = this.modalList.length-1;
            
            /* 공지사항 갯수만큼 v-for 돌리기위해 값 받아옴 */
            this.noticeList = this.modalList.length;
            
           /* 공지사항 Modal창 뜰 위치 */              
            top = 10+"%";            
            left = 35+"%";
         }
         })
         .catch(error =>{console.log(error)})   
        
        /* await으로 Notice Data 다 가져온 후에
          Modal창 여러개면 계단식으로 떨어지는 함수 시작 */
        this.modalStairs();
    },
    modalStairs(){
   	for (let i = 0; i < noticeList.length; i++) {
       	 top -= 10;
         left -= 10;         
         let notice = document.querySelector([`.drag${this.noticeNum}`]);
         notice.style.top = top+"%";
         notice.style.left = left+"%";
       }
    },    
   dragMouseDown(index){
   		/* 클릭 된 Modal에 제일 큰 zIndex 주기 위해 */              
   		if (document.onmousedown) zIndex++;         
        
        let notice = document.querySelector([`.drag${this.noticeNum}`]);
        notice.style.zIndex = zIndex;
        notice.style.cursor = 'move';
   
   		/* Drag 이벤트 시작 */              
        this.positions.clientX = index.clientX;
        this.positions.clientY = index.clientY;
        document.onmousemove = this.elementDrag;
        document.onmouseup = this.closeDragElement;
        document.onmousedown = this.mouseDown;
    },
    mouseDown(){
    	/* Drag 이벤트 시작하면 커서 손으로 잡고있는 모양으로 변경 */              
    	let notice = document.querySelector([`.drag${this.noticeNum}`]);
    	notice.style.cursor = 'grabbing';
    },
    elementDrag(event){
    	/* Drag 이벤트 하는 도중 현재Modal창 위치에서 마우스 x,y값 빼면서 드래그  */              
        this.positions.movementX = this.positions.clientX - event.clientX;
        this.positions.movementY = this.positions.clientY - event.clientY;

        this.positions.clientX = event.clientX;
        this.positions.clientY = event.clientY;

        let notice = document.querySelector([`.drag${this.noticeNum}`]);
        notice.style.top = (noticr.offsetTop - this.positions.movementY) + 'px';
        notice.style.left = (noticr.offsetLeft - this.positions.movementX) + 'px';
    },
    closeDragElement(){
    	/* Drag 이벤트 끝. 커서 다시 드래그 가능 표시로 변경 */              
       document.onmouseup = null;
       document.onmousemove = null;
       
   	   let notice = document.querySelector([`.drag${this.noticeNum}`]);
   	   notice.style.cursor = 'move';
    },
    close(index){
      /* Modal창 닫을때 noticeList에서 값을 하나씩 뺌 */     
     this.noticeNum = index;

    let notice = document.querySelector([`.drag${this.noticeNum}`]);
    notice.style.display = 'none';
    this.noticeList --;
    }, 
  },
};
</script>

<style lang="scss" scoped></style>
반응형