【vue3+vue-pdf-embed】實現PDF+圖片預覽
- 項目背景
- 項目代碼
- 分析代碼
項目背景
技術棧:vue3+Ts+elementplus
需要實現PDF和圖片預覽
圖片預覽很好解決了,可以用elementplus 自帶的組件el-image 可實現
PDF預覽可以用搜了一圈,有兩個方案,一個是vue-office-pdf,另一個是vue-pdf-embed
由于項目需求,只需要做預覽,且只支持 PDF,也不需要什么高級文檔操作功能,所以我就采用了vue-pdf-embed
項目代碼
html 代碼
<my-dialog ref="myDialogRef" width="60%" max-height="70vh"><div v-loading="dialogLoading" class="reviewDiv"><el-image v-if="imageDialogVisible" :src="imageSrc" style="max-width: 100%;" fit="contain" /><vue-pdf-embed v-else ref="pdfRef" :source="imageSrc" :page="pdfPage" @password-requested="handlePasswordRequest" @rendered="handleDocumentRender" /><div v-show="!imageDialogVisible && pageCount" class="text-center"><el-button :disabled="pdfPage <= 1" @click="pdfPage--">?</el-button><span class="mx-4">{{ pdfPage }} / {{ pageCount }}</span><el-button :disabled="pdfPage >= pageCount" @click="pdfPage++">?</el-button></div></div>
</my-dialog>
js 代碼
const imageSrc = ref('')
const myDialogRef = ref()
const imageDialogVisible = ref<boolean>(false)
const dialogLoading = ref<boolean>(false)
const openFileDialog = (file: any) => {dialogLoading.value = true// 釋放之前創建的對象URLif (imageSrc.value) {URL?.revokeObjectURL(imageSrc.value)}// 創建新的對象URLif (file.raw) {// 本地預覽imageSrc.value = URL?.createObjectURL(file.raw)dialogLoading.value = false} else {// 編輯遠程預覽const targetFile = getTargetFile.value(file)apiDownloadFile(targetFile[0].fileDocumentId).then((response: any) => {imageSrc.value = response.request.responseURLsetTimeout(() => {dialogLoading.value = false}, 1000)})}const isImage = judgeIcon(file) === 'image'myDialogRef.value?.openDialog(isImage ? '圖片預覽' : 'PDF預覽')if (isImage) {imageDialogVisible.value = true} else {imageDialogVisible.value = false}
}const pdfPage = ref<number>(1)
const pageCount = ref<number>(0)
const pdfRef = ref()
function handleDocumentRender () {pageCount.value = pdfRef.value?.doc?.numPages // 這里是重點
}function handlePasswordRequest (callback: any, retry: boolean) {callback(prompt(retry ? 'Enter password again' : 'Enter password'))
}
分析代碼
首先預覽有本地預覽和遠程預覽
- 本地預覽顧名思義:就是在本地上傳還沒有調接口的PDF或圖片進行預覽,這時候通過URL 接口里面的靜態方法并往里面傳file.raw 便可得到 本地PDF/圖片鏈接了
具體請看這里URL:createObjectURL() 靜態方法 - 遠程預覽:即從后端接口返回回來的PDF/圖片 進行預覽,這時候需要先調用下載接口 ,接口會返回 對應的鏈接
通過以上兩步:可以把 需要傳遞的 source 的值搞定
需要PDF很大,有很多頁,這時候預覽需要分頁,但是分頁的時候有一個問題,就是一直找不到對應的總頁碼即pageCount ,有看很多文章,要么通過rendered方法傳參,但文檔根據不支持傳參,
vue-pdf-embed
后面自己試了一下,居然 使用 ref 的方式 pdfRef.value?.doc?.numPages ,拿到了總頁碼,至此,后面就很容易解決了