一个Vue3 PDF阅读器组件及用法(功能可定制)

vue-pdf.js

 
安装
npm install @tuttarealstep/vue-pdf.js

使用:

<template>
  <div style="width:100%;height:100%;">
    <VuePDFjs
        ref="vuepdfjs"
        :source="pdfUrl"
        :options="options"
        @pdf-app:loaded="onPdfAppLoaded"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { VuePDFjs } from "@tuttarealstep/vue-pdf.js"
import "@tuttarealstep/vue-pdf.js/dist/style.css"
import zhCN_FTL from "@tuttarealstep/vue-pdf.js/l10n/zh-CN/viewer.ftl?raw"

const pdfUrl = "http://localhost:8080/uploads/manual/2025/07/23/511d5d55-0bee-4fe6-a402-040bba9f2a99.pdf"
const options = ref({
  toolbar: {
    options: {
      printButton: false, // 禁用打印
      downloadButton: false, // 禁用下载
      // secondaryToolbarToggle: false, // 下拉菜单切换按钮
      // secondaryToolbar: false, // 下拉菜单容器不显示,即便有按钮。
      secondaryDownload: false,
      secondaryOpenFile: false,
      secondaryPrint: false,
      // presentationMode: false, // 下拉菜单项:演示模式
      // editorFreeTextButton: false,      // Free text editing tool
      editorSignature: false,
      editorStamp: false,
      // editorHighlightButton: false,     // Highlight tool
      // editorInkButton: false,           // Drawing/ink tool
    }
  },
  locale: {
    code: "zh-CN", // 菜单项简体中文
    ftl: zhCN_FTL,
  },
})

const vuepdfjs = ref()

function onPdfAppLoaded() {
  console.log("pdf loaded")
  alert('pad加载完成')
  // 加载完成后打开侧边列表视图
  vuepdfjs.value.pdfApp.pdfSidebar.open()

  // 在PDF加载完成后,在顶部工具栏编辑按钮组容器里添加自定义按钮(全屏按钮)
  const editorModeButtons = document.getElementById('editorModeButtons');
  if (editorModeButtons) {
    // 添加 CSS 控制,解决添加按钮后显示问题
    const style = document.createElement('style');
    style.innerHTML = `
      #fullScreenButton::before {
        display:none;
      }
    `;
    document.head.appendChild(style);

    // 构建全屏按钮html代码
    const html = `
      <div id="fullScreen" class="toolbarButtonWithContainer">
        <button id="fullScreenButton" class="toolbarButton" title="全屏">
          <svg width="16" height="16" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
              <path fill="#515151" d="M145.066667 85.333333h153.6c25.6 0 42.666667-17.066667 42.666666-42.666666S324.266667 0 298.666667 0H34.133333C25.6 0 17.066667 8.533333 8.533333 17.066667 0 25.6 0 34.133333 0 42.666667v256c0 25.6 17.066667 42.666667 42.666667 42.666666s42.666667-17.066667 42.666666-42.666666V145.066667l230.4 230.4c17.066667 17.066667 42.666667 17.066667 59.733334 0 17.066667-17.066667 17.066667-42.666667 0-59.733334L145.066667 85.333333z m170.666666 563.2L162.133333 802.133333l-76.8 76.8V725.333333C85.333333 699.733333 68.266667 682.666667 42.666667 682.666667s-42.666667 17.066667-42.666667 42.666666v256c0 25.6 17.066667 42.666667 42.666667 42.666667h256c25.6 0 42.666667-17.066667 42.666666-42.666667s-17.066667-42.666667-42.666666-42.666666H145.066667l76.8-76.8 153.6-153.6c17.066667-17.066667 17.066667-42.666667 0-59.733334-17.066667-17.066667-42.666667-17.066667-59.733334 0z m665.6 34.133334c-25.6 0-42.666667 17.066667-42.666666 42.666666v153.6l-76.8-76.8-153.6-153.6c-17.066667-17.066667-42.666667-17.066667-59.733334 0-17.066667 17.066667-17.066667 42.666667 0 59.733334l153.6 153.6 76.8 76.8H725.333333c-25.6 0-42.666667 17.066667-42.666666 42.666666s17.066667 42.666667 42.666666 42.666667h256c25.6 0 42.666667-17.066667 42.666667-42.666667v-256c0-25.6-17.066667-42.666667-42.666667-42.666666z m0-682.666667h-256c-25.6 0-42.666667 17.066667-42.666666 42.666667s17.066667 42.666667 42.666666 42.666666h153.6l-76.8 76.8-153.6 153.6c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733334 0l153.6-153.6 76.8-76.8v153.6c0 25.6 17.066667 42.666667 42.666666 42.666666s42.666667-17.066667 42.666667-42.666666v-256c0-25.6-17.066667-42.666667-42.666667-42.666667z"></path></svg>
        </button>
      </div>
    `;
    const fullScreenButton = (new DOMParser()).parseFromString(html, 'text/html').body.firstChild;

    // 获取工具栏并添加按钮
    editorModeButtons.appendChild(fullScreenButton);

    // 添加点击事件
    document.getElementById('fullScreen').addEventListener('click', (event) => {
      console.log('全屏按钮被点击');
      const containerStyle = document.querySelector('.vue-pdfjs').style;
      const fullScreenButton = document.getElementById('fullScreenButton');

      if (fullScreenButton.title === '全屏') {
        // 全屏显示
        containerStyle.position = 'fixed';
        containerStyle.top = '0';
        containerStyle.bottom = '0';
        containerStyle.left = '0';
        containerStyle.right = '0';
        containerStyle.zIndex = '9999';
        containerStyle.height = 'unset';
        fullScreenButton.title= '退出全屏';
      } else {
        // 退出全屏
        containerStyle.position = 'unset';
        containerStyle.top = 'unset';
        containerStyle.bottom = 'unset';
        containerStyle.left = 'unset';
        containerStyle.right = 'unset';
        containerStyle.zIndex = 'unset';
        containerStyle.height = '800px'; // 还原高度
        fullScreenButton.title= '全屏';
      }

    });

  }
}


</script>

 

posted @ 2025-08-18 17:59  jsper  阅读(125)  评论(0)    收藏  举报