Dandy Now!
  • [개발자의품격][부트캠프][1기][20차시] Vue.js #19 | slot을 이용한 Modal
    2022년 04월 02일 22시 15분 50초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    부트캠프 20차시에서 Vue.js의 slot 기능을 적용한 Modal 구현을 실습하였는데 그 내용을 다음과 같이 정리하였다.

    자식 컴포넌트를 부트스트랩 디자인의 Modal 컴포넌트로 만들고 부모 컴포넌트에서 자식 컴포넌트를 이용해 하나 이상의 Modal을 구현하고자 한다.

     

    | 자식 컴포넌트

    부트스트랩 적용

    components의 fragments 폴더에 SlotModal.vue 파일을 생성한 후 <template> 태그 안에 "부트스트랩 > Components > Live demo"에서 <!-- Modal --> 이하를 copy 하여 붙여 넣는다.

    <!-- src/components/fragments/SlotModal.vue -->
    <template>
        <!-- Modal -->
        <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
          <div class="modal-dialog">
            <div class="modal-content">
              <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
              </div>
              <div class="modal-body">
                ...
              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
              </div>
            </div>
          </div>
        </div>
    </template>

     

    slot 및 v-bind 적용

    부모 컴포넌트에서 하나 이상의 Modal을 생성하기 위해서 id를 props의 modalId와 바인딩한다. modal-title, modal-body, modal-footer 부분에 slot 태그를 각각 적용한다.

    <!-- src/components/fragments/SlotModal.vue -->
    <template>
      <div
        class="modal fade"
        :id="modalId" // id를 props의 modalId와 바인딩한다.
        data-bs-backdrop="static"
        data-bs-keyboard="false"
        tabindex="-1"
        aria-labelledby="staticBackdropLabel"
        aria-hidden="true"
      >
        <div class="modal-dialog">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="staticBackdropLabel">
                <slot name="title"></slot> // 부모 컴포넌트로 부터 title을 받아 오기 위한 slot
              </h5>
              <button
                type="button"
                class="btn-close"
                data-bs-dismiss="modal"
                aria-label="Close"
              ></button>
            </div>
            <div class="modal-body">
              <slot name="body"></slot> // 부모 컴포넌트로 부터 body를 받아 오기 위한 slot
            </div>
            <div class="modal-footer">
              <slot name="footer"></slot> // 부모 컴포넌트로 부터 footer를 받아 오기 위한 slot
              <button type="button" class="btn btn-primary">Understood</button>
            </div>
          </div>
        </div>
      </div>
    </template>
    <script>
    export default {
      props: {
        // 부모 컴포넌트로 부터 모달 아이디를 받아오기 위한 modalId 객체를 작성한다.
        modalId: {
          type: String,
          default: 'myModal'
        }
      }
    }
    </script>

     

    | 부모 컴포넌트

    부모 컴포넌트에서는 위에서 작성한 자식 컴포넌트를 이용해 하나 이상의 Modal을 생성할 수 있다. 부트스트랩 Modal을 띄우기 위한 버튼의 toggle, target, 그리고 v-slot의 사용법을 잘 봐 두자!

    <!-- src/views/4_reuse/SlotView.vue -->
    <template>
      <div>
        <!-- 버튼에 부트스트랩 모달 toggle, target 적용, target 아이디를 달리하여 하나 이상의 모달을 생성할 수 있다. -->
        <button
          class="btn btn-primary me-1"
          data-bs-toggle="modal"
          data-bs-target="#staticBackdrop_1"
        >
          show Modal_1
        </button>
        <!-- 자식 컴포넌트 slot-modal 태그에 자식 컴포넌트 modalId에 전달할 모달 아이디 문자열을 넣는다. 이 아이디는 버튼의 target 아이디와 같아야 한다. --> 
        <slot-modal modalId="staticBackdrop_1">
          <!-- v-slot의 title, body, footer의 내용을 각각 작성한다. 모달의 제목과 내용을 작성하는 것이다. -->
          <template v-slot:title>모달창 타이틀_1</template>
          <template v-slot:body>
            <p>first_1</p>
            <p>second_1</p>
          </template>
          <template v-slot:footer>
            <button>저장</button>
          </template>
        </slot-modal>
        <!-- 위와 같이 두번째 버튼과 모달창을 작성한다. -->
        <button
          class="btn btn-primary"
          data-bs-toggle="modal"
          data-bs-target="#staticBackdrop_2"
        >
          show Modal_2
        </button>
        <slot-modal modalId="staticBackdrop_2">
          <template v-slot:title>모달창 타이틀_2</template>
          <template v-slot:body>
            <p>first_2</p>
            <p>second_2</p>
          </template>
          <template v-slot:footer>
            <button>저장</button>
          </template>
        </slot-modal>
      </div>
    </template>
    <script>
    // 자식 컴포넌트 import
    import SlotModal from '@/components/fragments/SlotModal.vue'
    export default {
      components: { SlotModal },
      data() {
        return {
        }
      }
    }
    </script>

     

    [그림 1] show Modal_2 버튼 클릭하여 띄운 모달

    728x90
    반응형
    댓글