[vue-pdf-embed@2] Lazy loading example
by hrynko
HTML
<script src="https://unpkg.com/vue@3.3.0/dist/vue.global.js"></script>
<script src="https://unpkg.com/vue-pdf-embed@2.1.0/dist/index.umd.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-pdf-embed@2.1.0/dist/styles/annotationLayer.css">
<link rel="stylesheet" href="https://unpkg.com/vue-pdf-embed@2.1.0/dist/styles/textLayer.css">
<template id="appTemplate">
<div class="app-content">
<div v-for="pageNum in pageNums" :key="pageNum" ref="pageRefs">
<vue-pdf-embed
v-if="pageVisibility[pageNum]"
:source="doc"
:page="pageNum"
/>
</div>
</div>
</template>
<div id="app"></div>
CSS
body {
margin: 0;
padding: 0;
background-color: #ccc;
}
.app-content {
padding: 24px 16px;
}
.app-content > * {
margin: 0 auto;
padding-bottom: 8px;
}
.vue-pdf-embed__page {
box-shadow: 0 2px 8px 4px rgba(0, 0, 0, 0.1);
}
JavaScript
Vue.createApp({
template: document.getElementById('appTemplate').innerHTML,
components: {
'vue-pdf-embed': VuePdfEmbed,
},
setup() {
const pageRefs = Vue.ref([])
const pageVisibility = Vue.ref({})
let pageIntersectionObserver
const { doc } = useVuePdfEmbed({
source: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf',
})
const pageNums = Vue.computed(() =>
doc.value
? [...Array(doc.value.numPages + 1).keys()].slice(1)
: []
)
const resetPageIntersectionObserver = () => {
pageIntersectionObserver?.disconnect()
pageIntersectionObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const index = pageRefs.value.indexOf(entry.target)
const pageNum = pageNums.value[index]
pageVisibility.value[pageNum] = true
}
})
})
pageRefs.value.forEach((element) => {
pageIntersectionObserver.observe(element)
})
}
Vue.watch(pageNums, (newPageNums) => {
pageVisibility.value = { [newPageNums[0]]: true }
Vue.nextTick(resetPageIntersectionObserver)
})
Vue.onBeforeUnmount(() => {
pageIntersectionObserver?.disconnect()
})
return {
doc,
pageNums,
pageRefs,
pageVisibility,
}
},
}).mount('#app')