很久以前,好吧,去年2月,我发布了关于用Vue.js使用Adobe PDF Embed库的文章。使用Vue.js的PDF嵌入API。我们的嵌入库和Vue等库的主要问题是一个 "鸡和蛋 "问题。基本上,我们的文档告诉你添加一个事件监听器来加载我们的库,但有可能在你添加事件监听器之前,库已经加载。
在我之前的文章中,我谈到了你仍然可以使用事件监听器,但也可以寻找window.AdobeDC ,看看它是否已经加载。这个方法适用于任何想要使用该库的框架,所以它是一个很好的提示。
今天,一个用户在我们的论坛上发帖说他们在库和Vue 3上有问题,虽然是完全不同的问题。
首先,他们没有遇到我上面所说的 "鸡/蛋 "问题。他们是在mounted 中动态加载我们的库:
mounted() {
document.addEventListener("adobe_dc_view_sdk.ready", () => {
this.adobeApiPDFReady = true;
console.log("Adobe created with adobe_dc_view_sdk.ready");
});
// Dynamically load Adobe SDK Viewer for this page
const plugin = document.createElement("script");
plugin.setAttribute(
"src",
"https://documentcloud.adobe.com/view-sdk/viewer.js"
);
plugin.async = true;
document.head.appendChild(plugin);
},
我喜欢这种方法!总之,他们为他们的PDF创建一个AdobeDCView对象没有问题。他们在this.adobeApiPDFReady 上使用了一个watch:
watch: {
adobeApiPDFReady(val) {
if (val) {
// val == true ; Adobe is loaded on page
this.adobeDCView = new window.AdobeDC.View({
clientId: "9861538238544ff39d37c6841344b78d",
divId: "pdfview",
});
}
console.log("Adobe is mounted with Client ID");
},
},
到目前为止还不错。然后他们用一个按钮来触发显示PDF:
<button @click="openPDF">Click to view file</button>
<div id="pdfview"></div>
这里是方法:
openPDF() {
console.log("Trying to open PDF");
// Opening preview with default settings from https://developer.adobe.com/document-services/docs/overview/pdf-embed-api/#live-demo
this.adobeDCView.previewFile(
{
content: {
location: {
url:
"/hamlet.pdf",
},
},
metaData: { fileName: "hamlet.pdf" },
},
{}
);
},
这都是我们文档中的模板,只是为Vue稍作修改,例如,this.adobeDCView 来表示Vue的数据。然而,当调用previewFile ,却返回了这个错误。
说实话,我完全不知道为什么会出现这个错误。似乎没有什么不妥。我确保了div元素被正确找到。我确保库真的被加载了。没有什么是有意义的。
然后--纯粹是一时兴起--我把adobeDCView 从一个Vue值(即在该组件的this 范围内)改为window.adobeDCView 。它开始工作了!
然后我试着这样做:
watch: {
adobeApiPDFReady(val) {
if (val) {
// val == true ; Adobe is loaded on page
this.adobeDCView = new window.AdobeDC.View({
clientId: "9861538238544ff39d37c6841344b78d",
divId: "pdfview",
});
}
window.ray = new window.AdobeDC.View({
clientId: "9861538238544ff39d37c6841344b78d",
divId: "pdfview",
});
}
console.log("Adobe is mounted with Client ID");
},
},
并在我的代码中调用previewFile ,做了:
console.log("Ray", this.adobeDCView);
console.log("Ray2", window.ray);
然后看到了这个。
注意Vue对象是一个代理,这是有道理的--Vue的数据是反应式的,所有。老实说,我不知道为什么我以前没有这个问题,但是Vue 3肯定是Vue 2的一个重大更新。所以,我不想使用一个窗口对象,因为它感觉......不对。我做了一些搜索,发现了StackOverflow的这个答案。如何使模板变量在Vue中不被反应,这导致了官方文档中关于使用Object.freeze() 的说明。
我简直就是在修改这个:
watch: {
adobeApiPDFReady(val) {
if (val) {
// val == true ; Adobe is loaded on page
this.adobeDCView = Object.freeze(new window.AdobeDC.View({
clientId: "9861538238544ff39d37c6841344b78d",
divId: "pdfview",
}));
}
console.log("Adobe is mounted with Client ID");
},
},
然后就成功了!这里有一个嵌入的CodeSandbox,显示了它的作用。
像往常一样,如果这对你不起作用,请让我知道!