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

相关推荐
2501_920931701 天前
React Native鸿蒙跨平台采用ScrollView的horizontal属性实现横向滚动实现特色游戏轮播和分类导航
javascript·react native·react.js·游戏·ecmascript·harmonyos
东东5161 天前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino1 天前
图片、文件的预览
前端·javascript
2501_920931701 天前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
AI老李1 天前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
方也_arkling1 天前
Element Plus主题色定制
javascript·sass
晓晓莺歌1 天前
vue3某一个路由切换,导致所有路由页面均变成空白页
前端·vue.js
2601_949809591 天前
flutter_for_openharmony家庭相册app实战+我的Tab实现
java·javascript·flutter
Up九五小庞1 天前
开源埋点分析平台 ClkLog 本地部署 + Web JS 埋点测试实战--九五小庞
前端·javascript·开源
摘星编程1 天前
React Native + OpenHarmony:UniversalLink通用链接
javascript·react native·react.js