지금 프로젝트가 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() 함수를 사용하는 것만으로 충분히
기능 구현이 가능할 것이다. 끝
'FrontEnd > JavaScript' 카테고리의 다른 글
[JS] ES6에서 import를 했는데 undefined값을 읽는 문제에 관한 이야기 (0) | 2023.11.23 |
---|---|
[JS] html2canvas + jspdf 조합으로 HTML에서 원하는 영역을 PDF로 변환해보자. (0) | 2023.11.13 |
[JS] window.print()를 이용해서 특정영역을 인쇄하는 기능을 구현하는 방법 (0) | 2023.11.11 |
[JS] 자바스크립트의 콜백(Callback)함수에 대한 개념 및 샘플코드를 통해 이해해보자. (1) | 2023.05.21 |
[JS] Promise.all를 통해 여러개의 프라미스를 병렬로 실행하고 모든 프라미스가 종료되는 시점을 잡아보자. (1) | 2023.05.20 |