<template> <el-dialog title="文档" :model-value="visible && model === 'dialog'" @update:model-value="visible = false" :append-to-body="appendToBody" > <div v-if="visible" style="height: 690px; overflow-y: auto"> <vue-pdf v-for="page in numOfPages" :key="page" :src="fnSrc(props.src)" :page="page" /> </div> </el-dialog> <div v-if="model === 'normal'" :key="src" style="height: 690px; overflow-y: auto" > <vue-pdf v-for="page in numOfPages" :key="page" :src="fnSrc(props.src)" :page="page" /> </div> </template> <script setup> import { watchEffect, ref } from "vue"; import { VuePdf, createLoadingTask } from "vue3-pdfjs/esm"; import { ElMessage } from "element-plus"; import { useVModel } from "@vueuse/core"; const VITE_FILE_URL = import.meta.env.VITE_FILE_URL; defineOptions({ name: "LayoutPdf", }); const props = defineProps({ src: { type: String, required: true, }, visible: { type: Boolean, default: false, }, model: { type: String, validator: (value) => { const typeList = ["dialog", "normal"]; if (typeList.includes(value)) { return true; } else { throw new Error(`model必须是${typeList.join("、")}之一`); } }, default: "dialog", }, appendToBody: { type: Boolean, default: false, }, }); const emits = defineEmits(["update:visible"]); const visible = useVModel(props, "visible", emits); const numOfPages = ref(0); const fnSrc = (src) => { if (!src) return; if (src.indexOf("http") !== -1 || src.indexOf("https") !== -1) return src; else return VITE_FILE_URL + src; }; watchEffect(() => { if (props.visible || props.src) { const loadingTask = createLoadingTask(fnSrc(props.src)); loadingTask.promise .then((pdf) => { numOfPages.value = pdf.numPages; }) .catch(() => { visible.value = false; ElMessage.error("文件加载失败"); }); } }); </script>