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

相关推荐
柚yuzumi16 分钟前
前端优化,从少触发一次开始:防抖与节流
前端·javascript
默_笙38 分钟前
🚤 CSS 布局的"圈地运动":BFC 就是浏览器的独立领地
前端·javascript
用户938515635071 小时前
大模型记忆指南:从短时缓存到永久记忆,手把手带你吃透 LangChain Memory 管理
javascript·人工智能
xqchen1 小时前
Web Components 普及困境深度解析:技术标准与工程实践的落差
javascript
爱丶不疚1 小时前
写给前端工程师的现代 Python 工程化最佳实践:从 pnpm 到 uv,从 CommonJS 到 src-layout
javascript·python·typescript
Dreams°1232 小时前
【Java后端+Vue前后端分离:内网正常、公网访问异常|5个高频经典踩坑完整复盘】
java·开发语言·vue.js
小蒜学长2 小时前
基于Springboot+Vue的环保行动志愿者招募系统设计与实现(代码+数据库+LW)
java·数据库·vue.js·spring boot·后端
天道kabuto3 小时前
踩坑复盘:为什么在输入框按个回车,页面就偷偷刷新了?
vue.js
2601_962097483 小时前
JavaScript 异步编程
javascript·ajax·回调函数·异步编程·子线程
吴长建先生3 小时前
Vue.js支付回调页面如何设计才能保障对账准确性?
vue.js