生成PDF后跳转指定路由services/pdf/:serviceId的问题求助
解决方案
问题出在你直接调用pdfMake.createPdf(docDefinitions).open()的方式——这个方法会直接创建新标签页渲染PDF二进制内容,和你的React路由完全无关,所以地址栏不会显示配置的/services/pdf/:serviceId。要实现点击按钮后跳转到指定路由并展示PDF,需要调整逻辑:
步骤1:修改按钮点击逻辑,跳转至目标路由
不再直接调用生成PDF的函数,而是用React Router的导航钩子跳转到目标路由,传入serviceId参数:
// 按钮所在组件中 import { useNavigate } from 'react-router-dom'; const YourComponent = () => { const navigate = useNavigate(); const serviceId = "获取实际的serviceId值"; // 替换为你实际的serviceId变量 const handleOpenPDFRoute = () => { navigate(`/services/pdf/${serviceId}`); }; return ( <Button variant="contained" sx={{ marginRight: '5px' }} onClick={handleOpenPDFRoute}> PDF </Button> ); };
步骤2:在TabPayment组件中生成并展示PDF
进入目标路由后,在TabPayment组件里读取路由参数,生成PDF并处理展示:
方式1:保持新标签页打开PDF(路由页面做中转)
// TabPayment组件 import { useEffect } from 'react'; import { useParams } from 'react-router-dom'; import pdfMake from 'pdfmake/build/pdfmake'; import pdfFonts from 'pdfmake/build/vfs_fonts'; pdfMake.vfs = pdfFonts.pdfMake.vfs; const TabPayment = () => { const { serviceId } = useParams<{ serviceId: string }>(); useEffect(() => { // 根据serviceId构建PDF内容 const docDefinitions = { content: [ `Service ID: ${serviceId}`, // 其他PDF内容 ] }; // 生成并打开PDF pdfMake.createPdf(docDefinitions).open(); // 可选:中转页面自动关闭(优化体验) setTimeout(() => window.close(), 1000); }, [serviceId]); return <div>正在生成PDF...</div>; }; export default TabPayment;
方式2:在路由页面内展示PDF(地址栏保持目标路由)
如果希望地址栏始终显示/services/pdf/:serviceId,可以将PDF生成为Blob,用embed标签在页面内渲染:
// TabPayment组件 import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import pdfMake from 'pdfmake/build/pdfmake'; import pdfFonts from 'pdfmake/build/vfs_fonts'; pdfMake.vfs = pdfFonts.pdfMake.vfs; const TabPayment = () => { const { serviceId } = useParams<{ serviceId: string }>(); const [pdfUrl, setPdfUrl] = useState<string | null>(null); useEffect(() => { const generatePDF = async () => { const docDefinitions = { content: [ `Service ID: ${serviceId}`, // 其他PDF内容 ] }; const pdfDoc = pdfMake.createPdf(docDefinitions); const blob = await pdfDoc.getBlob(); const url = URL.createObjectURL(blob); setPdfUrl(url); }; generatePDF(); // 清理Blob URL,避免内存泄漏 return () => { if (pdfUrl) URL.revokeObjectURL(pdfUrl); }; }, [serviceId]); if (!pdfUrl) return <div>正在生成PDF...</div>; return ( <div style={{ width: '100vw', height: '100vh' }}> <embed src={pdfUrl} type="application/pdf" width="100%" height="100%" /> </div> ); }; export default TabPayment;
路由配置注意事项
如果你使用的是React Router v6,需要将原路由配置更新为v6语法(移除exact,用element替代component):
// router.tsx <Route path="/services/pdf/:serviceId" element={<TabPayment />} />
内容的提问来源于stack exchange,提问作者LaraF
相关产品推荐
相关产品推荐

