<template>
<div>
<div id="exam">
<h2>文本 Example</h2>
<p>example example example example example example</p>
</div>
<br/><br/>
<button @click="output">Print</button><br/><br/><br/>
<p>Result:</p><br/>
<div id="res"></div>
</div>
</template>
<script lang="ts" setup>
import html2canvas from 'html2canvas'
const output = async () => {
const dom = document.getElementById('exam')
if (dom) {
const cvs = await html2canvas(dom)
document.getElementById('res')?.append(cvs)
}
}
</script>
html2canvas + vue3 + ts + sass.
I wonder how often I see developers using getElementById
or querySelector
in vue components. You should make sure to use so called template refs.
You might try the following approach (which I didn’t test, but something like this should work).
<div>
<div ref="exam">
<h2>文本 Example</h2>
<p>example example example example example example</p>
</div>
<div ref="result"></div>
</div>
// inside script setup
import html2canvas from 'html2canvas'
const exam = ref<HTMLDivElement | null>(null);
const result = ref<HTMLDivElement | null>(null);
const cvs = ref<??? | undefined>();
const output = async () => {
if (!exam.value || !result.value) return;
// saving the cvs value in a ref variable
// to keep it available on rerenderings.
cvs.value = await html2canvas(exam.value)
}
// add a watcher that append the result
// in order to apply it every time the
// something changes because vue will
// empty the element each time you update something.
watch(
cvs,
(newCvs) => {
if (!newCvs || !result.value) return;
// clean the result element
result.value.innerHTML = '';
// append the new created cvs
result.value.append(newCvs);
},
{ flush: 'post' },
)