vue-pdf 移动端分页查看pdf文件

本文介绍了一个使用 Vue.js 实现的移动端 PDF 查看器组件,支持分页查看和双指缩放功能。组件中通过 `vue-pdf` 库加载 PDF 文件,并提供了跳转至指定页码、前后翻页的功能。同时,详细展示了组件的 HTML 结构、样式及 Vue.js 脚本代码,包括页面初始化、路由离开时的处理等关键逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue-pdf 移动端分页查看pdf文件(支持双指缩放)

<template>
  <section class="pdf-container">
    <div v-show="loaded" class="m-vue-pdf">
      <Pdf
        :src="pdfUrl"
        :page="currentPage"
        @num-pages="totalCount = $event"
        @page-loaded="currentPage = $event"
        @loaded="loadPdfHandler"
      />
      <div class="m-page">
        <div class="m-left">
          <span class="u-label">跳至</span>
          <input v-model="jumpNum" type="number" class="u-input">
          <span class="u-unit"></span>
          <a class="u-button" @click="onJump">确定</a>
          <div class="assist" />
        </div>
        <div class="m-right">
          <svg
            viewBox="64 64 896 896"
            data-icon="left"
            :class="['u-arrow', { gray: currentPage === 1 }]"
            aria-hidden="true"
            focusable="false"
            @click="onPrePage"
          >
            <path
              d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
            />
          </svg>
          <span class="u-num">{{ currentPage }}/{{ totalCount }}</span>
          <svg
            :class="['u-arrow', { gray: currentPage === totalCount }]"
            viewBox="64 64 896 896"
            data-icon="right"
            aria-hidden="true"
            focusable="false"
            @click="onNextPage"
          >
            <path
              d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
            />
          </svg>
          <div class="assist" />
        </div>
      </div>
    </div>
  </section>
</template>
<script>
import Pdf from 'vue-pdf'
export default {
  naem: 'VuePdfJump',
  components: {
    Pdf
  },
  data () {
    return {
      loaded: false,
      numPages: '',
      currentPage: 1, // pdf文件页码
      totalCount: 0, // pdf文件总页数
      jumpNum: null,
      // 可引入网络文件或者本地文件
      pdfUrl: '', // 如果引入本地pdf文件,需要将pdf放在public文件夹下,引用时使用绝对路径(/:表示public文件夹)
      pdfName: ''
    }
  },
  created () {
    const { url} = this.$route.query
    this.pdfUrl = url
    var docEl = window.document.documentElement
    var width = window.screen.availWidth || window.screen.width
    var rootSize = width / 15
    docEl.style.fontSize = rootSize + 'px'
    // 当前页面允许双指缩放
    document
      .querySelector('meta[name="viewport"]')
      .setAttribute('content', 'width=device-width, initial-scale=1')
  },
  beforeRouteLeave (to, from, next) {
    // 离开页面取消双指缩放
    document
      .querySelector('meta[name="viewport"]')
      .setAttribute(
        'content',
        'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'
      )
    next()
  },
  methods: {
    onJump () {
      if (this.jumpNum) {
        if (
          Number(this.jumpNum) <= this.totalCount &&
          Number(this.jumpNum) >= 1
        ) {
          this.currentPage = Number(this.jumpNum)
          this.jumpNum = null
        } else {
          this.$toast('请输入正确的跳转页码', this.toastParams)
        }
      } else {
        this.$toast('请输入要跳转的页码', this.toastParams)
      }
    },
    onPrePage () {
      if (this.currentPage > 1) {
        this.currentPage--
      }
    },
    onNextPage () {
      if (this.currentPage < this.totalCount) {
        this.currentPage++
      }
    },
    // pdf加载时
    loadPdfHandler (e) {
      this.currentPage = 1 // 加载的时候先加载第一页
      this.loaded = true
    }
  }
}
</script>
<style lang="scss" scoped>
.pdf-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
}
.m-vue-pdf {
  flex: 1 0 auto;
  height: 0;
  overflow: scroll;
  padding-bottom: 40px;
  .back-box {
    position: fixed;
    top: 0;
  }
  .m-page {
    position: fixed;
    bottom: 0px;
    left: 0;
    right: 0;
    height: 40px;
    display: flex;
    align-items: center;
    z-index: 9;
    justify-content: space-between;
    background: #fff;
    .m-left {
      margin-left: 0.8rem;
      font-size: 14px;
      color: #333;
      .u-label {
        display: inline-block;
        vertical-align: middle;
      }
      .u-input {
        width: 1rem;
        height: 20px;
        border: 0.04rem solid #999;
        border-radius: 0.1rem;
        margin: 0 5px;
        text-align: center;
        background: #fff;
        outline: none;
        vertical-align: middle;
      }
      .u-unit {
        margin-right: 5px;
        vertical-align: middle;
      }
      .u-button {
        color: #333;
        display: inline-block;
        padding: 0.01rem 0.2rem;
        border-radius: 0.08rem;
        border: 0.04rem solid #999;
        font-size: 14px;
        background: transparent;
        outline: none;
        vertical-align: middle;
        -webkit-tap-highlight-color: transparent;
      }
      .assist {
        height: 100%;
        width: 0;
        display: inline-block;
        vertical-align: middle;
      }
    }
    .m-right {
      margin-right: 0.8rem;
      font-size: 14px;
      color: #333;
      .u-arrow {
        width: 14px;
        height: 14px;
        fill: #333;
        vertical-align: middle;
        cursor: pointer;
      }
      .gray {
        fill: #999;
        cursor: default;
      }
      .u-num {
        letter-spacing: 0.1rem;
        display: inline-block;
        margin: 0 0.2rem;
        vertical-align: middle;
      }
      .assist {
        height: 100%;
        width: 0;
        display: inline-block;
        vertical-align: middle;
      }
    }
  }
}
</style>

### 如何在 H5 中通过 `vue-pdf` 实现 PDF 分页功能 为了实现在 HTML5 (H5) 项目中使用 `vue-pdf` 插件来完成 PDF分页显示功能,可以按照以下方式构建解决方案。 #### 使用 `vue-pdf` 进行 PDF 预览的核心逻辑 `vue-pdf` 是一个基于 `pdf.js` 构建的 Vue 组件库,用于在前端实现 PDF 文件的解析与展示。它支持按需加载指定页面的内容,并允许开发者自定义样式和交互行为[^1]。 以下是具体实现方法: --- #### 解决方案代码示例 ##### 安装依赖 首先需要安装 `vue-pdf` 库: ```bash npm install vue-pdf ``` ##### 编写组件代码 创建一个 Vue 组件文件(如 `PdfViewer.vue`),并编写如下代码: ```html <template> <div class="pdf-container"> <!-- 动态渲染每一页 --> <pdf v-for="(page, index) in pages" :key="'page' + index" :src="pdfSrc" :page="index + 1" @num-pages="setTotalPages" @error="handleError" style="width: 100%; margin-bottom: 20px;" ></pdf> <!-- 页面切换按钮 --> <button @click="prevPage" :disabled="currentPage === 1">上一页</button> <span>第 {{ currentPage }} / {{ totalPages }} 页</span> <button @click="nextPage" :disabled="currentPage >= totalPages">下一页</button> </div> </template> <script> import pdf from 'vue-pdf'; export default { components: { pdf }, data() { return { pdfSrc: null, totalPages: 0, currentPage: 1, }; }, computed: { pages() { // 返回当前应加载的页数范围 return Array.from({ length: this.totalPages }, (_, i) => i); }, }, methods: { setTotalPages(total) { this.totalPages = total; }, handleError(error) { console.error('PDF 加载失败:', error); }, prevPage() { if (this.currentPage > 1) { this.currentPage -= 1; } }, nextPage() { if (this.currentPage < this.totalPages) { this.currentPage += 1; } }, }, mounted() { const loadingTask = pdf.createLoadingTask('/path/to/your/pdf-file.pdf'); this.pdfSrc = loadingTask; // 设置 PDF 源路径 }, }; </script> <style scoped> .pdf-container { text-align: center; } button { padding: 8px 16px; margin: 10px; } </style> ``` --- #### 关键点说明 1. **动态加载多页** - 利用 `v-for` 循环渲染多个 `<pdf>` 组件实例,分别对应不同的 PDF 页面编号。 - 当前总页数由事件监听器捕获并通过 `@num-pages` 属性传递给父级组件[^2]。 2. **性能优化** - 如果文档较大或者设备性能有限,建议仅加载可见区域内的页面,而非一次性加载全部页面。可以通过滚动检测等方式控制实际渲染的页码集合。 3. **移动端适配** - 对于移动环境下的应用开发,可能遇到兼容性问题。例如某些浏览器内置的安全策略会阻止跨域请求外部资源。此时可尝试修改底层工作线程配置文件中的特定设置项[^3]。 4. **错误处理机制** - 添加全局异常捕捉能力以便及时发现潜在风险因素;同时提供友好的用户体验提示信息代替生硬的技术报错描述。 --- #### 注意事项 - 确保目标服务器端已开启 CORS 支持以避免因同源政策限制引发访问权限冲突情况发生。 - 若计划部署至生产环境中,则考虑引入 CDN 或者静态化服务减少带宽消耗以及提升响应速度表现效果更佳。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值