【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 ,拿到了总页码,至此,后面就很容易解决了

相关推荐
ZC跨境爬虫7 小时前
跟着MDN学HTML_day_48:(Node接口)
前端·javascript·ui·html·音视频
kyriewen10 小时前
半夜三点线上崩了,AI替我背了锅——用AI排错,五分钟定位三年老bug
前端·javascript·ai编程
hexu_blog10 小时前
vue+java实现图片批量压缩
java·前端·vue.js
AI_paid_community11 小时前
98.5k Star!GitHub官方开源的这个工具,正在把"vibe coding"扫进历史的垃圾桶
javascript·claude
AI_paid_community11 小时前
用 Claude Code 写了一年代码,装了这 18 个 Skills 之后,我才知道自己一直在"氛围编程"
javascript·面试
parade岁月12 小时前
开源一个 Vue 3 Table:API 学 antdv、主题学 Nuxt UI
前端·vue.js
隔壁老王111112 小时前
浅谈JavaScript内存管理
javascript
吹牛不交税12 小时前
tree-transfer-vue3 前端插件安装问题解决(--legacy-peer-deps)(其他插件可考虑)适用
前端·javascript·vue.js
Appoint_x12 小时前
设计稿自己会说话:我用 Claude 给 Figma 做了个 AI 上下文插件
前端·javascript