【vue3+vue-pdf-embed】实现PDF+图片预览

【vue3+vue-pdf-embed】实现PDF+图片预览

项目背景

技术栈:vue3+Ts+elementplus

需要实现PDF和图片预览

图片预览很好解决了,可以用elementplus 自带的组件el-image 可实现

PDF预览可以用搜了一圈,有两个方案,一个是vue-office-pdf ,另一个是vue-pdf-embed

由于项目需求,只需要做预览 ,且只支持 PDF ,也不需要什么高级文档操作功能,所以我就采用了vue-pdf-embed

项目代码

html 代码

javascript 复制代码
<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 代码

javascript 复制代码
const imageSrc = ref('')
const myDialogRef = ref()
const imageDialogVisible = ref<boolean>(false)
const dialogLoading = ref<boolean>(false)
const openFileDialog = (file: any) => {
  dialogLoading.value = true
  // 释放之前创建的对象URL
  if (imageSrc.value) {
    URL?.revokeObjectURL(imageSrc.value)
  }
  // 创建新的对象URL
  if (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.responseURL
      setTimeout(() => {
        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'))
}

分析代码

首先预览有本地预览和远程预览

  1. 本地预览顾名思义:就是在本地上传还没有调接口的PDF或图片进行预览,这时候通过URL 接口里面的静态方法并往里面传file.raw 便可得到 本地PDF/图片链接了
    具体请看这里URL:createObjectURL() 静态方法
  2. 远程预览:即从后端接口返回回来的PDF/图片 进行预览,这时候需要先调用下载接口 ,接口会返回 对应的链接
    通过以上两步:可以把 需要传递的 source 的值搞定

需要PDF很大,有很多页,这时候预览需要分页,但是分页的时候有一个问题,就是一直找不到对应的总页码即pageCount ,有看很多文章,要么通过rendered方法传参,但文档根据不支持传参,
vue-pdf-embed

后面自己试了一下,居然 使用 ref 的方式 pdfRef.value?.doc?.numPages ,拿到了总页码,至此,后面就很容易解决了

相关推荐
sorryhc1 分钟前
【AI解读源码系列】ant design mobile——CapsuleTabs胶囊选项卡
前端·javascript·react.js
巧克力7916 分钟前
js数组去重的方法
javascript·面试
Sheeep19 分钟前
Cursor 的使用之学会使用 cursor rule
javascript·后端
本末倒置1831 小时前
Svelte邪修的JSDoc,到底是个啥?
前端·javascript·面试
李明卫杭州1 小时前
CSS中的background-clip详解
前端·javascript
荻酷社区1 小时前
HTML+CSS+JavaScript实现的AES加密工具网页应用,包含完整的UI界面和加密/解密功能
javascript·css·html
彭于晏爱编程2 小时前
密码的,YOU不能不知道的Next.jsSSR(服务端渲染)
前端·javascript·react.js
yvvvy2 小时前
前端性能优化全家桶:从重绘重排到面试连招,一篇搞懂
前端·javascript·面试
小蒜学长2 小时前
vue家教预约平台设计与实现(代码+数据库+LW)
java·数据库·vue.js·spring boot·后端
串串狗xk2 小时前
使用 webgl 写的新概念笔记应用《赛博城寨》,在三维开放世界里写笔记
javascript·webgl