توسعه‌دهندگان همواره نمایشگرهای PDF را دست‌کم می‌گیرند. به نظر می‌رسد مسئله‌ای ساده مثل «یک فایل در یک جعبه» باشد؛ بایت‌ها را دریافت می‌کنید، یک کامپوننت را به URL متصل می‌کنید و کار تمام است. Vue.js باعث می‌شود بیشتر کارهای رابط کاربری به همین سادگی به نظر برسند، اما یک نمایشگر PDF آماده برای محیط عملیاتی (production-ready) از آن ویژگی‌هایی است که بی‌صدا گسترش می‌یابد و کل اسپرینت‌ها را می‌بلعد. من طی دو هفته، یک نمایشگر مشابه را به چهار روش مختلف ساختم. هر تلاش، همان نکته را به وضوح ثابت کرد: کتابخانه‌ای که روز دوشنبه انتخاب می‌کنید، تعیین می‌کند که دو ماه بعد مشغول رفع کدام باگ‌ها خواهید بود.

تله‌ی آموزش‌های قدیمی

اکثر راهنماها هنوز کتابخانه‌هایی را توصیه می‌کنند که آخرین بار زمانی به‌روزرسانی شده‌اند که Vue 2 استاندارد اصلی بود. یک توسعه‌دهنده نگاهی گذرا به README می‌اندازد، دستور نصب را اجرا می‌کند و تصور می‌کند بخش سخت کار تمام شده است. در واقعیت، بخش سخت تازه شروع شده است. شما به قابلیت جستجو نیاز خواهید داشت. باید بتوانید یک سند سیاستی ۴۰۰ صفحه‌ای را بدون کرش کردن تب مرورگر مدیریت کنید. کسی در موبایل خواهد پرسید که چرا قابلیت pinch-to-zoom (بزرگ‌نمایی با دو انگشت) درست کار نمی‌کند. در README به‌ندرت درباره این مسائل هشدار داده می‌شود، زیرا دمو معمولاً فقط صفحه اول یک مقاله علمی پنج صفحه‌ای را رندر می‌کند.

چهار رویکرد اصلی

هیچ کتابخانه PDF واحدی که «بهترین» برای Vue باشد وجود ندارد. فقط کتابخانه‌ای وجود دارد که «بهترین تناسب» را با آنچه کاربران واقعاً می‌خواهند انجام دهند، داشته باشد.

PDF.js: مسیر DIY (خودت انجام بده)

PDF.js موزیلا، موتور زیرساختی تقریباً تمام نمایشگرهای مبتنی بر وب است. استفاده از آن در یک اپلیکیشن Vue 3 به معنای نصب یک کامپوننت نیست؛ بلکه به معنای پذیرفتن یک پروژه است. شما سند را با getDocument دریافت می‌کنید، هر صفحه را در یک عنصر <canvas> رندر می‌کنید و آن کانواس‌ها را به قالب (template) خود متصل می‌کنید. روز اول احساس بهره‌وری می‌کنید. تا روز سوم، مشغول پیکربندی اسکریپت worker هستید تا با باندلینگ Vite و هدرهای CORS سازگار باشد.

اسکرول بومی مرورگر برای ده صفحه خوب کار می‌کند، اما برای هزار صفحه از کار می‌افتد، بنابراین شما باید اسکرول مجازی (virtual scrolling) بسازید. سپس متوجه می‌شوید که متن‌ها قابل انتخاب نیستند، بنابراین لایه‌هایی از divهای متنی شفاف را روی هر کانواس قرار می‌دهید. چاپ کردن تار به نظر می‌رسد، بنابراین به دنبال تنظیمات DPI و media queryها می‌گردید. قابلیت pinch-to-zoom در موبایل با مدیریت ژست‌های بومی مرورگر درگیر می‌شود. جستجوی بین اسناد به معنای استخراج و ایندکس کردن متن در تمام صفحات به صورت ناهمگام (asynchronously) و سپس ساخت رابط کاربری است که نتایج را بدون مسدود کردن رشته اصلی (main thread) در صف قرار دهد. حتی با وجود یک دستیار کدنویسی هوش مصنوعی مانند Cursor که کدهای اولیه (boilerplate) را تولید می‌کند، معماری همچنان بر عهده شماست. بخش‌های سخت ناپدید نمی‌شوند؛ بلکه به کد شما منتقل می‌شوند. این مسیر تنها زمانی منطقی است که نیازهای شما واقعاً محدود و خاص باشد، یا زمانی که چندین هفته وقت آزاد داشته باشید و دلیل محکمی برای اجتناب از رفتارهای آماده (off-the-shelf) داشته باشید.

vue-pdf-embed: مسیر سبک

گاهی اوقات تمام چیزی که نیاز دارید، نمایش فایل است. vue-pdf-embed یک کامپوننت Vue 3 است که یک منبع را می‌پذیرد و صفحات را به صورت یک پشته عمودی رندر می‌کند. نصب و یکپارچه‌سازی آن چند دقیقه زمان می‌برد. برای یک پنل مدیریت داخلی که فاکتورهای تولید شده یا گزارش‌های انطباق را نمایش می‌دهد، این اغلب دقیقاً همان چیزی است که نیاز دارید. کامپوننت رندر کردن کانواس را مدیریت می‌کند و کاربران شما می‌توانند اسکرول کنند.

هزینه این کار، از دست دادن تمام قابلیت‌های دیگر است. هیچ نوار ابزار، جستجوی سند، نوار کناری تصاویر بندانگشتی (thumbnail) و هیچ راهی برای پیمایش صفحات (به جز اسکرول کردن در کانتینر) وجود ندارد. لحظه‌ای که یک ذینفع می‌پرسد: «آیا می‌توانم شماره فاکتور را جستجو کنم؟»، یکپارچه‌سازی دو ساعته شما به یک ساختار سفارشی و سنگین تبدیل می‌شود. زمانی این را انتخاب کنید که PDFهای شما کوتاه هستند، مخاطبان شما داخلی هستند و مدل تعامل صرفاً اسکرول کردن برای مطالعه (read-only) است.

@tato30/vue-pdf: مسیر کنترل‌محور

این کتابخانه از یک کامپوننت یکپارچه (monolithic) به یک composable تغییر شکل می‌دهد. این کتابخانه usePDF را ارائه می‌دهد که آن را در بلوک setup خود فراخوانی می‌کنید. به جای رندر کردن کل یک سند اسکرول‌شونده، شما هر بار یک صفحه را از طریق refهای واکنش‌گرا (reactive refs) مدیریت می‌کنید. این کار اضافی به نظر می‌رسد، اما زمانی که رابط کاربری نیاز به دقت بالا دارد، رهایی‌بخش است.

یک ابزار بررسی خسارت بیمه را تصور کنید که در آن کارشناسان یک صفحه از سند را تأیید می‌کنند، روی Next کلیک می‌کنند و سیستم هر رویداد مشاهده را ثبت می‌کند. یک نمایشگر اسکرول‌شونده پیوسته، استعاره اشتباهی برای این مورد است. شما یک صفحه‌بندی کنترل‌شده می‌خواهید، شاید با قابلیت ثبت نظر در سطح صفحه یا دکمه‌های تأیید که مستقیماً به شاخص صفحه فعلی متصل هستند. از آنجایی که usePDF تعداد صفحات و صفحه فعلی را به عنوان داده‌های واکنش‌گرا به شما می‌دهد، متصل کردن آن به یک نوار ناوبری سفارشی یا یک نشانگر پیشرفت، بسیار طبیعی به نظر می‌رسد. شما همچنان باید ظاهر (chrome) اطراف کانواس را بسازید، اما از کدهای تکراری و اولیه رندرینگ در پایین‌ترین سطح رها می‌شوید. این برای اپلیکیشن‌هایی مناسب است که در آن‌ها کاربران به جای مرور سریع یک نسخه خطی کامل، صفحات را یکی یکی بررسی می‌کنند.

Vue PDF Viewer: مسیر خدمات کامل

زمانی فرا می‌رسد که بازسازی قابلیت‌های نمایشگر، از تمرکز بر محصول اصلی شما بکاهد. Vue PDF Viewer یک کامپوننت تجاری است که با نوار ابزار کامل، جستجوی متن، یادداشت‌گذاری، واکنش‌گرایی موبایل و اسکرول مجازی که در تمامی موارد خاص (edge cases) تست شده‌اند، عرضه می‌شود. وظیفه شما به جای اختراع مجدد، به پیکربندی تبدیل می‌شود. شما تم را با سیستم طراحی خود مطابقت می‌دهید، قابلیت‌های مورد نیاز را فعال می‌کنید و به سراغ کارهایی می‌روید که واقعاً اپلیکیشن شما را متمایز می‌کنند.

هزینه لایسنس اولیه واقعی است، اما هزینه دو هفته زمان مهندسی که صرف بازسازی لایه‌های نمایه‌سازی جستجو و یادداشت‌گذاری می‌شود نیز واقعیت دارد. زمانی که در حال عرضه یک اپلیکیشن عملیاتی با یک ضرب‌الاجل واقعی هستید و کاربران شما انتظار تجربه‌ای مشابه با نرم‌افزارهای PDF دسکتاپ را دارند، این ابزار مناسب‌ترین انتخاب است.

هزینه واقعی نصب چقدر است

بزرگترین اشتباه این است که دستور npm install را به عنوان قیمت کل در نظر بگیرید. هزینه واقعی، چیزی است که پس از اتمام نصب می‌سازید. یک کتابخانه سبک در روز اول ارزان است، اما در روز بیستم که متوجه می‌شوید به نوار جستجو نیاز دارید، گران تمام می‌شود. مسیر DIY در روز اول رایگان است، اما در روز شصتم که هنوز در حال اصلاح اهداف لمسی موبایل و استایل‌شیت‌های چاپ هستید، گران تمام می‌شود. مسیر تجاری در ابتدا هزینه دارد، اما می‌تواند هفته‌ها از زمان مهندسی شما را ذخیره کند تا بتوانید آن را صرف منطق تجاری اصلی خود کنید.

یک کتابخانه را فقط به این دلیل که README آن کوتاه و دوستانه است انتخاب نکنید. بر اساس نیازهای پروژه خود انتخاب کنید. وجود یک نوار کناری شامل تصاویر بندانگشتی، جستجوی متن و یادداشت‌گذاری سمت کلاینت، شما را به سمت یک راهکار کامل هدایت می‌کند. یک پیش‌نمایش سریع رسید در داخل یک داشبورد داخلی، شما را به سمت یک مدل جایگذاری (embed) سبک هدایت می‌کند.

نتیجه‌گیری نهایی

قبل از اینکه برای هر کتابخانه Vue PDF تصمیم نهایی بگیرید، دقیقاً بنویسید که کاربران شما نیاز به انجام چه کاری دارند. اگر آن‌ها فقط نیاز دارند در اسناد کوتاه اسکرول کنند، vue-pdf-embed کار شما را راه می‌اندازد. اگر آن‌ها در یک گردش کار کنترل‌شده صفحات را ورق می‌زنند، از @tato30/vue-pdf استفاده کنید. اگر آن‌ها در یک اپلیکیشن حیاتی کسب‌وکار نیاز به یادداشت‌گذاری، جستجو و چاپ دارند، یک نمایشگر تجاری بخرید. و اگر نیازهای شما واقعاً منحصربه‌فرد است اما زمان‌بندی شما منعطف است، هفته‌ها وقت بگذارید و مستقیماً روی PDF.js کار کنید. یک نمایشگر PDF هرگز فقط یک فایل در یک جعبه نیست؛ بلکه یک رابط کاربری کامل برای اسناد است و انتخاب شما از بلوک‌های سازنده، تعیین می‌کند که آیا محصول خود را همین ماه عرضه می‌کنید یا در فصل آینده.