在Vue 3中使用Adobe PDF EMbed API的详细指南(附代码)

734 阅读3分钟

很久以前,好吧,去年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,显示了它的作用。

像往常一样,如果这对你不起作用,请让我知道!