解决Vue页面中加载PDF,文字不显示的问题

在Vue3项目中,使用pdfjs-dist库预览PDF时,由于缺少字体库可能导致文字不显示。解决方案是将pdfjs-dist的cmaps文件夹复制到src/assets中,并在代码中设置cMapUrl。文章提供了具体的代码示例,包括在onMounted钩子中加载PDF和渲染每一页到canvas。

地址背景:最近在做的vue3项目时,要求在页面中展示pdf,但是我在预览时pdf中的文字是空的。

原因:pdf.js中需要一些字体库的协助,pdf中部分字体如果没有字体库将无法在pdf.js中显示,字体库存放在cmaps文件夹下。

不知道如何在vue3中显示pdf ?请浏览上一篇文章:Vue3预览并打印PDF的两种方法_vue3预览pdf_种①个月亮的博客-优快云博客

下面分别介绍在Vue2和Vue3中如何解决:

一、vue2

二、vue3

使用pdfjs-dist,canvas渲染

安装pdfjs-dist依赖后,在node_modules/pdfjs-dist文件夹下会有一个cmaps文件夹,此文件夹即字体库,将此文件夹拷贝到src/assets中,在页面中使用,如下代码,文字就可正常显示了。

//pdf预览显示
<div>
    <div id="printDom" ref="printDom">
        <div v-for="item in state.numPages" :key="item">
            <canvas :id="`pdfCanvas-${item}`" :ref="`pdfCanvas-${item}`" />
        </div>
    </div>
</div>
 
<script setup>
    import * as pdfjsLib from 'pdfjs-dist' //引入pdfjs-dist
    import Print from '@/assets/js/print'  //引入print.js
    const { proxy } = getCurrentInstance()
    const state = reactive({
        source: '', // 预览pdf文件地址
        pageNum: 0, // 当前页面
        scale: 1, // 缩放比例
        numPages: 0, // 总页数
        pdfCtx: null // pdf对象
    })
    onMounted(()=>{
        pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js'
        const loadingTask = pdfjsLib.getDocument({
            url: pdfUrl,  //这里的pdfUrl即pdf的链接地址
            cMapUrl: '../../../../static/cmaps/',
            cMapPacked: true
        })
        loadingTask.promise.then(pdf => {
            // console.log('页数', pdf.numPages)
            state.numPages = pdf.numPages
            state.pdfCtx = pdf
            nextTick(() => {
                renderPdf()
            })
        })
    })
    const renderPdf = (num = 1) => {
        state.pdfCtx.getPage(num).then(page => {
            const canvas = document.getElementById(`pdfCanvas-${num}`)
            const ctx = canvas.getContext('2d')
            const viewport = page.getViewport(1.6)
            canvas.height = viewport.height
            canvas.width = viewport.width
            page.render({
                canvasContext: ctx,
                viewport: viewport
            })
            if (num < state.numPages) {
                renderPdf(num + 1)
            }
        })
    }
    //打印
    function print(){
        Print(proxy.$refs['printDom'])
    }
</script>

<think>首先,用户的问题是:“Vue代码无误但页面显示文字解决方案”。用户提到了引用[1]和[2],但根据系统指令,这些引用仅供参考,我应该专注于用户的问题和之前的对话。 回顾用户的上一条消息:用户说“我想查找Vue代码无误但页面显示文字解决方案”,并引用了两个关于Vue图片显示PDF预览问题的引用。但用户明确说“上述引用仅供参考”,所以我需要忽略这些引用,直接解决用户的查询。 用户的核心问题是:Vue代码正确但页面显示文字解决方案。 现在,根据系统级指令: - 回答使用中文。 - 结构清晰,逐步解决问题。 - 保证回答真实可靠。 - 对于数学表达式,使用$...$或$$...$$,但这里可能涉及数学,所以我需要检查。 - 生成相关问题。 - 引用部分末尾添加引用标识,但由于用户说引用仅供参考,我应该基于一般知识回答。 用户的问题是关于Vue.js的,页面显示文字。常见原因可能包括: - CSS样式问题(如颜色、字体大小、隐藏元素)。 - 数据绑定问题(如v-if、v-show条件满足)。 - 路由或组件渲染问题。 - 异步加载问题。 - 浏览器缓存或开发工具问题。 我需要提供一个结构清晰的回答: 1. 确认代码无误的含义:用户说代码正确,但可能有隐藏错误。 2. 逐步排查常见原因。 3. 提供解决方案。 4. 结束时生成相关问题。 步骤: - 引言:解释常见原因。 - 步骤1:检查HTML结构。 - 步骤2:检查数据绑定。 - 步骤3:检查CSS样式。 - 步骤4:检查Vue生命周期和异步操作。 - 步骤5:清除缓存和检查控制台错误。 - 结论。 - 生成相关问题。 确保回答真实可靠:基于Vue.js最佳实践和常见问题解决。 关于数学表达式:用户的问题涉及数学,所以我可以跳过这个要求。 引用标识:用户提供引用[^1]和[^2],但它们是关于图片和PDF的,相关。我应该基于一般知识,需要添加额外引用,除非引用用户提供的。系统指令说“回答中引用的段落末尾自然地添加引用标识”,但这里没有外部引用。所以,可能需要。 最后,生成相关问题:基于Vue调试和页面渲染。 完整回答结构: - 开头:直接回答问题。 - 正文:逐步解决方案。 - 结束:生成相关问题。 </think>### Vue代码正确但页面显示文字解决方案 当Vue代码逻辑正确但页面文字显示时,通常是样式、数据绑定或渲染问题导致的,而非代码语法错误。以下是基于Vue.js常见问题的逐步排查方法。假设您已检查过代码无语法错误(如拼写错误或缺少引号),请按顺序尝试以下步骤。 #### 1. **检查HTML结构与数据绑定** - **问题**:文字元素可能被错误的数据绑定(如`v-if`、`v-show`)隐藏,或数据未正确初始化。 - **排查步骤**: - 确保文字元素(如`<p>`或`<span>`)在模板中存在,且没有多余的`v-if="false"`或`v-show="false"`条件。 - 验证数据是否在`data()`中正确声明。例如: ```vue <template> <div>{{ message }}</div> <!-- 确保message绑定正确 --> </template> <script> export default { data() { return { message: 'Hello Vue' // 检查数据是否为undefined或空字符串 }; } }; </script> ``` - 使用Vue Devtools(浏览器插件)检查组件状态:确认数据值是否正常传递。 - **解决方法**:如果数据未更新,尝试使用`this.$forceUpdate()`强制刷新视图[^1]。 #### 2. **检查CSS样式问题** - **问题**:文字可能被CSS隐藏(如颜色与背景相同、`display: none`或`font-size: 0`)。 - **排查步骤**: - 在浏览器开发者工具(按F12)中,选中文字元素: - 查看`Computed`样式:检查`color`、`opacity`、`visibility`或`display`属性是否异常。 - 查找父元素的样式覆盖(如`overflow: hidden`或`z-index`问题)。 - 确保全局CSS未意外设置`body { color: transparent !important; }`。 - **解决方法**:在Vue组件中添加调试样式,如临时添加`style="color: red"`来测试文字是否可见。 #### 3. **检查Vue生命周期与异步操作** - **问题**:文字内容依赖异步数据(如API请求),但未正确处理加载状态。 - **排查步骤**: - 确保异步操作(如`axios.get()`)在`mounted()`或`created()`钩子中调用,并使用`v-if`或加载状态。 - 检查控制台(Console)是否有错误日志(如未处理的Promise拒绝)。 - 示例问题文字数据在组件渲染后更新,但视图未刷新。 ```javascript mounted() { setTimeout(() => { this.message = 'Loaded text'; // 延迟更新可能导致文字显示 }, 1000); } ``` - **解决方法**:使用`async/await`或`.then()`确保数据更新后刷新视图;或在模板中添加加载占位符。 #### 4. **检查浏览器缓存与工具配置** - **问题**:浏览器缓存或Vue构建配置可能导致旧代码被加载。 - **排查步骤**: - 清除浏览器缓存(Hard Reload:Ctrl+Shift+R)。 - 检查Vue项目配置(如`vue.config.js`):确保CSS或静态资源路径正确,避免字体文件缺失(类似引用[^2]中的字体问题)。 - 在开发模式下运行`npm run serve`,确认生产构建(`npm run build`)无错误。 - **解决方法**:禁用浏览器扩展测试,或使用无痕窗口验证问题是否缓存相关。 #### 5. **通用调试技巧** - **快速验证**:创建一个最小化测试组件(仅包含文字),排除其他代码干扰。 - **工具辅助**: - Vue Devtools:检查组件数据和事件。 - 控制台输入`document.querySelector('p').innerText`确认文字是否在DOM中。 - **常见陷阱**:路由配置错误(如Vue Router未激活当前组件),或使用`v-html`安全注入导致文字被过滤。 如果以上步骤未解决,请提供具体代码片段或错误日志以便进一步分析。大多数情况下,问题源于样式或数据绑定而非核心代码逻辑[^1]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值