Các nhà phát triển thường xuyên đánh giá thấp các trình xem PDF. Nó có vẻ như là một bài toán nạp file đơn giản. Bạn lấy các byte, trỏ một component vào URL, và coi như xong. Vue.js khiến hầu hết các công việc về UI cảm thấy rất trực quan, nhưng một trình xem PDF sẵn sàng cho môi trường production lại là một trong những tính năng âm thầm tiêu tốn cả những sprint làm việc. Tôi đã xây dựng cùng một trình xem theo bốn cách khác nhau trong vòng hai tuần. Mỗi lần thử nghiệm đều khẳng định một điều: thư viện bạn chọn vào thứ Hai sẽ quyết định những lỗi mà bạn phải đi sửa vào hai tháng sau đó.

Cái bẫy của những hướng dẫn lỗi thời

Hầu hết các hướng dẫn vẫn đề xuất các thư viện được cập nhật lần cuối từ thời Vue 2 còn là mặc định. Một lập trình viên lướt qua README, chạy lệnh cài đặt và cho rằng phần khó nhất đã xong. Thực tế là phần khó nhất chỉ mới bắt đầu. Bạn sẽ cần tính năng tìm kiếm. Bạn sẽ cần xử lý một tài liệu chính sách dài 400 trang mà không làm treo tab trình duyệt. Người dùng trên di động sẽ thắc mắc tại sao tính năng pinch-to-zoom lại hoạt động không mượt mà. README hiếm khi cảnh báo bạn về những điều này vì bản demo chỉ hiển thị trang đầu tiên của một bài báo khoa học dài năm trang.

Bốn cách tiếp cận

Không có một thư viện PDF duy nhất nào là tốt nhất cho Vue. Chỉ có thư viện phù hợp nhất với những gì người dùng của bạn thực sự muốn thực hiện.

PDF.js: Con đường tự thân (DIY)

PDF.js của Mozilla là công cụ cốt lõi bên dưới hầu hết mọi trình xem dựa trên web. Việc đưa nó vào một ứng dụng Vue 3 không có nghĩa là cài đặt một component; nó có nghĩa là bạn đang tiếp nhận cả một dự án. Bạn lấy tài liệu bằng getDocument, render từng trang vào một phần tử <canvas>, và kết nối các canvas đó vào template của mình. Ngày đầu tiên, bạn cảm thấy làm việc rất hiệu quả. Đến ngày thứ ba, bạn đang phải cấu hình worker script để nó hoạt động trơn tru với Vite bundling và các header CORS.

Cuộn trình duyệt mặc định hoạt động tốt với mười trang. Nhưng nó sẽ bị nghẽn với một nghìn trang, vì vậy bạn phải xây dựng tính năng virtual scrolling. Sau đó, bạn nhận ra văn bản không thể được chọn, vì vậy bạn phải phủ các thẻ div văn bản trong suốt lên trên mỗi canvas. Việc in ấn trông bị mờ, nên bạn phải tìm hiểu các cài đặt DPI và media queries. Tính năng pinch-to-zoom trên di động xung đột với việc xử lý cử chỉ mặc định của trình duyệt. Tìm kiếm xuyên tài liệu có nghĩa là phải trích xuất và lập chỉ mục văn bản trên mọi trang một cách bất đồng bộ, sau đó xây dựng một UI để xếp hàng các kết quả mà không làm chặn luồng chính (main thread). Ngay cả khi có một trợ lý lập trình AI như Cursor tạo mã boilerplate, bạn vẫn là người chịu trách nhiệm về kiến trúc. Những phần khó khăn không hề biến mất; chúng chỉ chuyển dịch vào mã nguồn của bạn. Hướng đi này chỉ hợp lý khi các yêu cầu của bạn thực sự đặc thù, hoặc khi bạn có vài tuần rảnh rỗi và có lý do chính đáng để tránh các hành vi mặc định của các thư viện có sẵn.

vue-pdf-embed: Con đường nhẹ nhàng

Đôi khi tất cả những gì bạn cần chỉ là hiển thị tệp tin. vue-pdf-embed là một component Vue 3 nhận một nguồn (source) và render các trang theo dạng xếp chồng theo chiều dọc. Việc cài đặt và tích hợp chỉ mất vài phút. Đối với một bảng điều khiển admin nội bộ hiển thị các hóa đơn được tạo hoặc các báo cáo tuân thủ, điều này thường là vừa đủ. Component này xử lý việc render canvas, và người dùng của bạn có thể cuộn.

Sự đánh đổi là tất cả những thứ còn lại. Không có thanh công cụ, không có tìm kiếm tài liệu, không có thanh bên chứa ảnh thu nhỏ (thumbnail), và không có điều hướng trang ngoài việc cuộn qua container. Ngay khi một bên liên quan hỏi: "Tôi có thể tìm số hóa đơn không?", việc tích hợp hai giờ của bạn sẽ phình to thành một bản build tùy chỉnh. Hãy chọn giải pháp này khi các tệp PDF của bạn ngắn, đối tượng người dùng là nội bộ, và mô hình tương tác thuần túy là cuộn để đọc.

@tato30/vue-pdf: Con đường kiểm soát

Thư viện này thay đổi hình thái từ một component nguyên khối sang một composable. Nó cung cấp usePDF, thứ mà bạn sẽ gọi bên trong khối setup. Thay vì render toàn bộ tài liệu có thể cuộn, bạn quản lý từng trang một thông qua các reactive refs. Nghe có vẻ như là thêm việc, nhưng nó sẽ giải phóng bạn khi giao diện đòi hỏi sự chính xác.

Hãy tưởng tượng một công cụ xem xét yêu cầu bảo hiểm, nơi các giám định viên xác minh từng trang tài liệu, nhấn Tiếp theo (Next), và hệ thống ghi lại từng sự kiện xem. Một trình xem cuộn liên tục sẽ không phải là một phép ẩn dụ phù hợp ở đây. Bạn muốn một bộ phân trang có kiểm soát, có thể đi kèm với tính năng bình luận ở cấp độ trang hoặc các nút phê duyệt được liên kết trực tiếp với chỉ số trang hiện tại. Vì usePDF cung cấp cho bạn số lượng trang và trang hiện tại dưới dạng dữ liệu reactive, việc kết nối nó với một thanh điều hướng tùy chỉnh hoặc một thanh hiển thị tiến trình sẽ cảm thấy rất tự nhiên. Bạn vẫn phải xây dựng phần khung (chrome) xung quanh canvas, nhưng bạn thoát khỏi được các mã boilerplate render ở cấp độ thấp nhất. Điều này phù hợp với các ứng dụng mà người dùng xem qua từng trang một thay vì lướt qua toàn bộ bản thảo.

Vue PDF Viewer: Con đường dịch vụ trọn gói

Sẽ đến lúc việc xây dựng lại các tính năng của trình xem trở thành một sự xao nhãng khỏi sản phẩm thực tế của bạn. Vue PDF Viewer là một thành phần thương mại đi kèm với thanh công cụ đầy đủ, tìm kiếm văn bản, chú thích, khả năng tương thích di động và cuộn ảo đã được kiểm thử qua các trường hợp biên. Công việc của bạn sẽ trở thành cấu hình thay vì tự chế. Bạn điều chỉnh giao diện để phù hợp với hệ thống thiết kế của mình, bật/tắt các tính năng cần thiết và tiếp tục tập trung vào những công việc thực sự tạo nên sự khác biệt cho ứng dụng của bạn.

Phí bản quyền trả trước là có thật, nhưng chi phí cho hai tuần phát triển kỹ thuật để tái tạo các lớp lập chỉ mục tìm kiếm và chú thích cũng là có thật. Đây là công cụ phù hợp khi bạn đang triển khai một ứng dụng thực tế dưới áp lực thời gian thực và người dùng của bạn mong đợi một trải nghiệm tương đương với các phần mềm PDF trên máy tính.

Chi phí thực sự của việc cài đặt

Sai lầm lớn nhất là coi lệnh npm install là tổng chi phí. Chi phí thực sự nằm ở những gì bạn xây dựng sau khi quá trình cài đặt kết thúc. Một thư viện nhẹ thì rẻ vào ngày đầu tiên nhưng lại đắt đỏ vào ngày thứ hai mươi khi bạn nhận ra mình cần một thanh tìm kiếm. Hướng đi DIY thì miễn phí vào ngày đầu tiên nhưng lại đắt đỏ vào ngày thứ sáu mươi khi bạn vẫn đang loay hoay sửa các vùng chạm trên di động và bảng kiểu in. Hướng đi thương mại tốn tiền ngay từ đầu, nhưng nó có thể tiết kiệm cho bạn hàng tuần phát triển kỹ thuật để bạn dành thời gian đó cho logic nghiệp vụ thực sự của mình.

Đừng chọn một thư viện chỉ vì tệp README của nó ngắn gọn và thân thiện. Hãy chọn dựa trên yêu cầu dự án của bạn. Một thanh bên chứa ảnh thu nhỏ, tìm kiếm văn bản và chú thích phía client sẽ hướng bạn đến một giải pháp toàn diện. Một bản xem trước biên lai nhanh chóng bên trong bảng điều khiển nội bộ sẽ hướng bạn đến một giải pháp nhúng nhẹ.

Bài học thực tế

Trước khi bạn quyết định chọn bất kỳ thư viện Vue PDF nào, hãy viết ra chính xác những gì người dùng của bạn cần làm. Nếu họ chỉ đơn giản cần cuộn qua các tài liệu ngắn, vue-pdf-embed sẽ đáp ứng tốt. Nếu họ thực hiện qua các trang trong một quy trình làm việc được kiểm soát, hãy chọn @tato30/vue-pdf. Nếu họ cần chú thích, tìm kiếm và in ấn bên trong một ứng dụng quan trọng của doanh nghiệp, hãy mua trình xem thương mại. Và nếu các yêu cầu của bạn thực sự độc đáo nhưng thời gian của bạn linh hoạt, hãy dành ra vài tuần và xây dựng trực tiếp trên PDF.js. Một trình xem PDF không bao giờ chỉ là một tệp tin nằm trong một chiếc hộp. Nó là một giao diện tài liệu đầy đủ, và lựa chọn nền tảng của bạn sẽ quyết định việc bạn sẽ triển khai trong tháng này hay quý tới.