본문 바로가기
보드게임 긱 추천 게임
Wizard Thumbnail
BoardGameGeek 사이트에서 인기순위 상위 100개 중 랜덤 3개를 보여줍니다.
BGG
귀펀치토끼는 부서지지 않는다.
주소(D)
영웅은 공부 따원 안 한다네/뷰

[Vue.js] 모달

<template>
  <div
    v-if="props.isVisible"
    class="modal_notice_save_content_container"
  >
    <div
      class="wrap_modal_notice_save_content"
      :style="getModalStyle"
      @mousedown="modalClick"
      @mouseup="modalClickOut"
      @mousemove="modalMove"
      @mouseout="modalClickOut"
    >
      <div class="wrap_modal_notice_save_content_title">
        <p class="modal_notice_save_content_title">
          알림
        </p>
        <img
          src="@assets/x_close_icon.svg"
          @click="onClose()"
        >
      </div>
      <div class="modal_notice_save_content">
        <div class="inquiry_unique_note_modal">
          <div class="wrap_unique_note_contents">
            <p class="torder_title_xs">
              내용
            </p>
            <textarea class="upload_contents"/>
          </div>
          <div class="wrap_uploader">
            <p class="torder_title_xs">
              등록자
            </p>
            <!-- <input
            type="text"
            class="torder_select_md"
            :value="uploader"
            readonly
          > -->
            <input
              type="text"
              class="torder_select_md"
              :value="'세션작성자'"
              readonly
            >
          </div>
          <div class="wrap_upload_date">
            <p class="torder_title_xs">
              등록일시
            </p>
            <input
              type="date"
              class="torder_select_md"
              :value="currentDate"
              readonly
            >
          </div>
        </div>
      </div>
      <div class="wrap_button_list">
        <button
          class="torder_file_input_button_md"
          @click="onClose()"
        >
          확인
        </button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  defineProps,
  ref,
  Ref,
  computed,
  reactive,
} from 'vue';

const props = defineProps({
  isVisible: {
    type: Boolean,
    default: false,
  },
  onClose: {
    type: Function,
    required: true,
  },
});

const modalPosition = reactive({
  left: '50%',
  top: '50%',
});
const currentDate = new Date().toISOString().substring(0, 10);
const modalPositionLeft = ref('50%');
const modalPositionTop = ref('50%');

const getModalStyle = computed(() => ({
  left: modalPositionLeft.value,
  top: modalPositionTop.value,
}));

const modalStartPosition = ref({
  left: 0,
  top: 0,
});

const isMoveModal = ref(false);

const mouseStartPosition = ref({
  left: 0,
  top: 0,
});

const modalClick = (event: any) => {
  const container: any = document.querySelector('.wrap_modal_notice_save_content');

  modalStartPosition.value.left = container.offsetLeft;
  modalStartPosition.value.top = container.offsetTop;
  mouseStartPosition.value.left = event.screenX;
  mouseStartPosition.value.top = event.screenY;
  isMoveModal.value = true;

  console.log(modalStartPosition.value);
};

const modalClickOut = () => {
  isMoveModal.value = false;
};

const modalMove = (event: any) => {
  if (isMoveModal.value) {
    modalPositionLeft.value = `${modalStartPosition.value.left + (event.screenX - mouseStartPosition.value.left)}px`;
    modalPositionTop.value = `${modalStartPosition.value.top + (event.screenY - mouseStartPosition.value.top)}px`;
  }
};
</script>

<style lang="scss" scoped>
.inquiry_unique_note_modal_container {
  display: flex;
  align-items: center;
  justify-content: center;

  .wrap_inquiry_unique_note_modal {
    position: fixed;
    top: 50%;
    left: 50%;
    z-index: 1;
    box-sizing: border-box;
    width: 740px;
    height: 530px;
    padding: 25px 25px 30px;
    background-color: #fff;
    border: solid 1px #000;
    border-radius: 10px;
    transform: translate(-50%, -50%);

    .wrap_inquiry_unique_note_modal_title {
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding-bottom: 15px;
      border-bottom: solid 1px #707070;

      .inquiry_unique_note_modal_title {
        font-size: 22px;
        font-weight: bold;
        letter-spacing: -1.1px;
      }
    }

    .inquiry_unique_note_modal {
      display: flex;
      flex-direction: column;
      gap: 10px;
      margin-top: 25px;

      >div {
        display: flex;
        align-items: center;
      }

      .wrap_unique_note_information {
        align-items: flex-start;

        .torder_title_xs {
          display: flex;
          align-items: center;
          height: 38px;
          margin-top: 10px;
        }

        .unique_note_information {
          display: flex;
          gap: 5px;
          align-items: flex-end;

          .wrap_modal_checkbox {
            box-sizing: border-box;
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            column-gap: 10px;
            align-items: center;
            justify-content: center;
            width: 561px;
            padding: 10px;
            background-color: #f6f6f6;
            border-radius: 5px;

            .modal_checkbox {
              display: flex;
              gap: 5px;
              align-items: center;
              height: 38px;
            }
          }
        }

        .unique_note_department {
          box-sizing: border-box;
          display: grid;
          grid-template-columns: repeat(4, 1fr);
          column-gap: 10px;
          align-items: center;
          justify-content: center;
          width: 561px;
          padding: 10px;
          background-color: #f6f6f6;
          border-radius: 5px;

          .modal_checkbox {
            display: flex;
            gap: 5px;
            align-items: center;
            height: 38px;
          }
        }
      }

      .wrap_unique_note_contents {
        align-items: flex-start;

        .torder_title_xs {
          display: flex;
          align-items: center;
          height: 38px;
        }

        .upload_contents {
          box-sizing: border-box;
          width: 561px;
          height: 260px;
          padding: 10px 12px;
          resize: none;
          background-color: #fcfcfc;
          border: solid 1px #e9e8eb;
          border-radius: 3px;
          box-shadow: inset 2px 2px 2px 0 rgba(0, 0, 0, 0.05);
        }
      }
    }

    .wrap_button_list {
      display: flex;
      gap: 5px;
      align-items: center;
      justify-content: center;
      margin-top: 25px;

      :first-child {
        background-color: #b6b5be;
      }
    }
  }
}

// SCSS
</style>
// 모달 부서선택 관련 데이터 및 함수
const isModalSelectDepartment = ref(false);
const onModalSelectDepartment = () => {
  isModalSelectDepartment.value = true;
};
const clostModalSearchCondition = () => {
  isModalSelectDepartment.value = false;
};
완료
내 컴퓨터