Vue PDF 組件初始不加載 pdfUrl 問題分析與修復
問題現象
在開發 PDF 預覽組件時,遇到這樣一個問題:
- 初始狀態下,PDF 組件不會請求 pdfUrl(即不會加載 PDF 文件)。
- 只有點擊"全屏"按鈕后,才會請求 pdfUrl 并渲染 PDF。
- 退出全屏后,PDF 也能正常顯示。
- 但如果不點擊全屏,PDF 一直無法加載。
現象復現
- 打開頁面,傳入 pdfUrl,PDF 區域顯示 loading,但實際沒有發起 pdfUrl 請求。
- 點擊全屏按鈕,PDF 能正常加載。
- 退出全屏后,非全屏下也能正常顯示 PDF。
代碼結構簡析
組件核心代碼片段如下:
<!-- 非全屏 PDF 渲染 -->
<div v-if="isPdfLoading" class="loading-container">...</div>
<div v-else class="pdf-content" ref="pdfContainer"><VuePdfEmbed ... />
</div><!-- 全屏 PDF 渲染 -->
<VuePdfEmbed v-if="isFullscreen" ... />
- 非全屏時,只有
isPdfLoading
為 false,<VuePdfEmbed ... />
才會渲染。 - 全屏時,
<VuePdfEmbed v-if="isFullscreen" ... />
直接渲染。
問題根源
- 組件通過監聽 pdfUrl 變化,將
isPdfLoading
設為 true。 - 但此時
<VuePdfEmbed ... />
沒有渲染到 DOM,自然不會發起 pdfUrl 請求。 - 只有在全屏時,
<VuePdfEmbed ... />
被掛載,才會請求 pdfUrl。 - 一旦 PDF 加載成功,
isPdfLoading
變為 false,非全屏下的<VuePdfEmbed ... />
才能渲染。
本質原因: loading 狀態用 v-if/v-else 隱藏了 PDF 組件,導致其無法掛載和發起請求。
修復方案
讓 PDF 組件始終掛載,只用 loading 遮罩覆蓋 UI,不用 v-if/v-else 隱藏 PDF 組件。
修復后代碼:
<div class="pdf-content" ref="pdfContainer"><VuePdfEmbed ... /><div v-if="isPdfLoading" class="loading-container" style="..."><v-progress-circular ... /><p>{{ loadingText }}</p></div>
</div>
這樣 <VuePdfEmbed ... />
始終在 DOM 中,pdfUrl 變化時能立即發起請求,loading 只是遮罩。
經驗教訓
- loading 狀態建議用遮罩而不是 v-if/v-else 隱藏內容組件,避免副作用。
- 組件的掛載時機直接影響其副作用(如發起請求、生命周期鉤子等)。
- 復雜交互下,建議用顯式的 UI 層覆蓋而不是條件渲染。
總結
本次問題的根源在于 loading 狀態的處理方式。通過調整渲染邏輯,讓 PDF 組件始終掛載,成功解決了 PDF 組件初始不加載 pdfUrl 的問題。希望本次經驗能為類似場景提供參考。