更新记录

0.2.3(2026-05-07)

  • 调整:iOS 端暂时取消上一页、下一页原生翻页栏,仅保留 PDF 基础渲染能力,优先保证 iOS 加载稳定性
  • 保留:Android 端继续保留分页模式下的原生上一页、下一页按钮和页码显示
  • 修复:iOS 端回退到最小 PDFView 渲染路径,移除翻页按钮、页码栏和 target-action 相关实现,降低下载加载 PDF 后闪退风险
  • 优化:iOS PDF 加载继续使用本地文件 URL、主线程渲染和渲染任务序号控制,避免重复触发渲染
  • 修复:补回 components/view-pdf/view-pdf.uvue 标准组件入口,改用 <native-view> 绑定原生实现,避免同名组件递归
  • 文档:明确当前版本分页能力以 Android 为主,iOS 后续稳定后再恢复翻页能力

0.2.2(2026-05-07)

  • 修复:兼容 HBuilderX 5.07 / uni-app x 编译器,修复 Android UTS 中 HashMap.values()keySet()size() 按 Java 方法调用导致的编译失败
  • 修复:Android 页面缓存遍历改为 MutableIterator 显式类型,解决 hasNext()next()Bitmap.recycle() 类型推断连锁报错
  • 修复:Android/iOS 原生组件资源释放生命周期由 onUnload 调整为 NVBeforeUnload,解决 onUnload overrides nothing 编译失败
  • 优化:清理调试入口中的模板日志输出,减少发布前控制台噪音
  • 优化:补全普通 uni-app 和 uni-app x demo,覆盖 PDF 加载、错误地址、分页方法、加载状态和截图展示
  • 文档:确认 view-pdf 已纳入已上架插件备注
  • 文档:保留原有使用文档和历史更新记录,避免影响已上架版本说明

0.2.1(2026-05-07)

  • 优化:清理调试入口中的模板日志输出,减少发布前控制台噪音
  • 优化:补全普通 uni-app 和 uni-app x demo,覆盖 PDF 加载、错误地址、分页方法、加载状态和截图展示
  • 文档:确认 view-pdf 已纳入已上架插件备注
  • 文档:保留原有使用文档和历史更新记录,避免影响已上架版本说明
查看更多

平台兼容性

uni-app(5.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- 5.0 12 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(5.0)

Chrome Safari Android iOS 鸿蒙 微信小程序
5.0 12 - -

其他

多语言 暗黑模式 宽屏模式
× ×

view-pdf(uni-app + uni-app x)

view-pdf 是一个支持 uni-appuni-app x 的 PDF 查看器插件,支持多平台展示 PDF 文档。

功能特性

  • 支持 paged 分页查看
  • 支持 scroll 全文滚动查看
  • 支持 quality 清晰度调节
  • 支持 zoom 缩放倍率调节
  • 支持页面跳转、获取当前页和总页数
  • 支持页面切换事件
  • 多平台兼容:H5、App(Android/iOS)

平台支持

平台 支持情况 说明
H5 ✅ 支持 使用 PDF.js
App-Android ✅ 支持 使用 PdfRenderer 原生组件
App-iOS ✅ 支持 使用 PDFKit 原生组件
小程序 ❌ 暂不支持 需使用 webview

安装

将插件目录放入项目:

  • uni_modules/view-pdf

uni-app 使用示例

H5 平台

<template>
  <view class="page">
    <view-pdf 
      class="viewer" 
      :url="pdfUrl" 
      :quality="3" 
      :zoom="1.4" 
      mode="scroll"
      @load="onLoad"
      @error="onError"
      @pageChange="onPageChange"
      ref="pdfViewer"
    />
  </view>
</template>

<script setup>
import { ref } from 'vue'

const pdfViewer = ref(null)
const pdfUrl = ref('https://example.com/sample.pdf')
const statusText = ref('等待加载')
const pageText = ref('')

const onLoad = (e) => {
  statusText.value = 'PDF 加载成功'
}

const onError = (e) => {
  statusText.value = e.errMsg || 'PDF 加载失败'
}

const onPageChange = (e) => {
  pageText.value = `${e.currentPage}/${e.totalPages}`
}

const goToPage = (pageIndex) => {
  pdfViewer.value.goToPage(pageIndex)
}

const getCurrentPage = () => {
  pdfViewer.value.getCurrentPageIndex().then(index => {
    pageText.value = `当前页:${index}`
  })
}

const getTotalPages = () => {
  pdfViewer.value.getTotalPages().then(total => {
    pageText.value = `总页数:${total}`
  })
}
</script>

<style>
.page {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.viewer {
  flex: 1;
}
</style>

App 平台(本地文件)

<template>
  <view class="page">
    <view-pdf 
      class="viewer" 
      :url="pdfPath" 
      :quality="2" 
      :zoom="1" 
      mode="paged"
      @load="onLoad"
      @error="onError"
      @pageChange="onPageChange"
      ref="pdfViewer"
    />
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const pdfViewer = ref(null)
const pdfPath = ref('')
const statusText = ref('等待加载')
const pageText = ref('')

onMounted(() => {
  downloadPdf()
})

const downloadPdf = () => {
  uni.downloadFile({
    url: 'https://example.com/sample.pdf',
    success: (res) => {
      if (res.statusCode === 200 && res.tempFilePath) {
        pdfPath.value = res.tempFilePath
      }
    },
    fail: (err) => {
      statusText.value = err.errMsg || '下载失败'
    }
  })
}

const onLoad = (e) => {
  statusText.value = 'PDF 加载成功'
}

const onError = (e) => {
  statusText.value = e.errMsg || 'PDF 加载失败'
}

const onPageChange = (e) => {
  pageText.value = `${e.currentPage}/${e.totalPages}`
}

const goToPage = (pageIndex) => {
  pdfViewer.value.goToPage(pageIndex)
}

const getCurrentPage = () => {
  const index = pdfViewer.value.getCurrentPageIndex()
  pageText.value = `当前页:${index}`
}

const getTotalPages = () => {
  const total = pdfViewer.value.getTotalPages()
  pageText.value = `总页数:${total}`
}
</script>

<style>
.page {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.viewer {
  flex: 1;
}
</style>

uni-app x 使用示例

<template>
  <view class="page">
    <view-pdf class="viewer" :url="pdfPath" :quality="3" :zoom="1.4" mode="scroll" />
  </view>
</template>

<script setup lang="uts">
import { ref } from 'vue'

const pdfPath = ref('')

uni.downloadFile({
  url: 'https://mirrors.tuna.tsinghua.edu.cn/CTAN/info/lshort/chinese/lshort-zh-cn.pdf',
  success: (res) => {
    if (res.statusCode == 200 && res.tempFilePath.length > 0) {
      pdfPath.value = res.tempFilePath
    }
  }
})
</script>

<style>
.page {
  flex: 1;
}

.viewer {
  flex: 1;
}
</style>

属性

  • url: string PDF 路径(H5支持网络URL,App建议传本地路径)
  • quality: number 清晰度倍率,默认 2,范围 1~4
  • zoom: number 缩放倍率,默认 1,范围 0.5~4
  • mode: string 查看模式:paged(分页) / scroll(滚动)

事件

  • load:加载成功
    { errMsg: 'view-pdf:ok' }
  • error:加载失败
    { errMsg: '错误信息' }
  • pageChange:页面切换
    { currentPage: 1, totalPages: 10 }

方法

  • goToPage(pageIndex: number): boolean - 跳转到指定页
  • getCurrentPageIndex(): number | Promise<number> - 获取当前页索引
  • getTotalPages(): number | Promise<number> - 获取总页数

说明

H5 平台

  • 使用 PDF.js 库进行渲染
  • 支持网络 URL 直接访问
  • 需要跨域支持或使用代理

App 平台

  • 使用原生 PDF 渲染组件,性能更好
  • 网络 PDF 建议先下载为本地临时文件后再传入
  • Android 使用 PdfRenderer,iOS 使用 PDFKit
  • 若出现空白,优先检查组件容器是否有有效高度

性能优化建议

  • 对于大文件,建议使用 paged 模式
  • 调整 qualityzoom 参数以平衡性能和显示质量
  • Android 端实现了页面缓存机制,提升切换页面的性能

常见问题

Q: H5 端网络 PDF 无法加载?

A: 请确保 PDF 服务器支持跨域访问,或使用代理服务器。

Q: App 端显示空白?

A: 请检查:

  1. 组件容器是否设置了高度
  2. PDF 文件路径是否正确
  3. 文件是否有读取权限

Q: 如何处理大文件?

A: 建议:

  1. 使用 paged 模式而非 scroll 模式
  2. 适当降低 quality 参数
  3. 考虑分片加载

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。