개발공작소
article thumbnail
728x90
반응형

 

 

 

 

지금 프로젝트가 Vue기반의 프로젝트라, 각 기능들을 Vue 컴포넌트로 빼서 사용하고 있는데

이때 인쇄 기능을 만들어야 했다. 

 

그런데 구현하는데 뭔가 잘 되지 않았다..

 

발생문제와 원인

 

1. 발생문제와 작성코드

 

우선 발생한 문제는 아래와 같다.

 

인쇄하고자 하는 모달화면

 

인쇄 미리보기 화면

 

 

작성코드

<template>
  <div id="modalSheet" class="modal modal-sheet position-static d-block bg-secondary py-5" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
      <div id="print-content" class="modal-content rounded-6 shadow">
        <div class="modal-header border-bottom-0">
          <h5 class="modal-title"><input :value="msg" /></h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body py-0">
          <p>This is a modal sheet, a variation of the modal that docs itself to the bottom of the viewport like the
            newer share sheets in iOS.</p>
        </div>
        <div class="modal-footer flex-column border-top-0">
          <button type="button" class="btn btn-lg btn-primary w-100 mx-0 mb-2" @click="showPrint()">인쇄 미리보기</button>
          <button type="button" class="btn btn-lg btn-light w-100 mx-0" data-bs-dismiss="modal">Close</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap'

export default {
  name: 'PrintComponent',
  props: {
    msg: String
  },
  methods: {
    showPrint() {

      const prtContent = document.getElementById('print-content')
      const initBody = document.body.innerHTML

      window.onbeforeprint = this.beforePrint(prtContent)
      window.onafterprint = this.afterPrint(initBody)
      window.print()
    },

    beforePrint(prtContent) {
      document.body.innerHTML = prtContent.innerHTML
    },

    afterPrint(initBody) {
      document.body.innerHTML = initBody
    }
  }

}
</script>

 

 

분명 웹화면상에는 텍스트가 제대로 들어가 있는데, 이상하게 인쇄 미리보기만 하면 해당 텍스트가 

사라지는 문제였다. (근데 생각해보면 사라지는게 당연하긴 함..)

 

 

2. 문제가 발생한 원인

 

이건 Vue의 데이터바인딩과 관련된 게 원인인데.. 작성코드와 결과화면을 보고 이야기 하도록하자.

 

 

(Vue) v-bind:value 작성코드

<h5 class="modal-title"><input :value="msg" /></h5>

 

 

결과화면

 

 

 

 

 

(HTML) value 작성코드

<h5 class="modal-title"><input value="msg" /></h5>

 

 

결과화면

 

 

 

 

 

결과화면을 비교해보면 알 수 있다.

 

v-bind를 이용하여 데이터바인딩을 한 경우 그려진 DOM의  input태그에 value값이 들어가지 않는다.

하지만 일반 value 속성을 사용한 경우에는 그려진 DOM의 input태그에 value값이 들어간다.

 

window.print() 함수 자체가 DOM을 인쇄 하는 함수인데

DOM의 value값이 할당 되지 않았으니, 내가 예상한 대로 기능이 작동하지 않았던 것..

 

 

 

 

문제해결

 

 

결론만 말하면 v-bind:value를 사용하지 않고 '{{ }}'를 사용하는 것으로 마무리 했다.

 

'{{ }}'를 사용하면 DOM에 해당 데이터가 그려지기 때문인데..

 

이렇게 하면 문제 없이 window.print() 함수를 사용할 수 있다.

 

 

샘플코드

<h5 class="modal-title">{{msg}}</h5>

 

 

결과화면

 

 

 

 

이렇게 문제를 해결 했다고는 적었지만, 실제로 이번에 window.print 함수를 사용하지 않았다.

나중에 시간을 내서 글을 작성하겠지만, print 관련 라이브러리를 사용하여 기능을 구현하였다.

 

1) print-js라이브러리

2) html2canvas + jspdf 조합

 

인데, 나는 html2canvas + jspdf 조합으로 기능을 구현하였다. 

 

하지만 위처럼 '{{ }}'을 사용한다면 window.print() 함수를 사용하는 것만으로 충분히

기능 구현이 가능할 것이다. 끝

 

 

728x90
반응형
profile

개발공작소

@모찌바라기

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!