0

我正在使用最新的 vue-pdf 包在我的应用程序中显示 pdf 文件。我构建了这个组件,PdfViewer:

<template>
  <div class="fill-height pdf-container">
    <template v-if="src && numberOfPages">
      <pdf
        v-for="page in numberOfPages"
        :key="`${fileName}-${page}`"
        :src="src"
        :page="page"
      />
    </template>
  </div>
</template>
import { mapGetters } from 'vuex'
import pdf from 'vue-pdf'

export default {
  props: {
    fileName: {
      type: String,
      required: true
    }
  },
  components: {
    pdf
  },
  data() {
    return {
      src: null,
      numberOfPages: 0
    }
  },
  computed: {
    ...mapGetters({
      getAttachments: 'questions/getAttachments'
    })
  },
  methods: {
    init() {
      if (this.fileName) {
        let url = this.getAttachments[this.fileName]
        let loadingTask = pdf.createLoadingTask(url)
        this.src = loadingTask
        this.src.promise.then(pdf => {
          this.numberOfPages = pdf.numPages
        })
      }
    },
  },
  watch: {
    fileName() {
      this.init()
    }
  },
  beforeMount() {
    this.init()
  }
}

基本上我收到一个文件名作为道具,然后在我在getAttachmentsgetter 中收到的对象中查找它的 URL。文件名位于不同的列表组件中。

它在第一次运行时运行良好,并且第一个文件已成功加载并显示。但是一旦单击另一个文件名 - 什么都没有显示。我确实收到了文件名道具,它确实找到了 URL,但文件没有显示。即使我点击已经显示的文件 - 现在它没有。

我想也许它与srcnumberOfPages属性有关,所以我尝试在加载文件之前重置它们:

init() {
      if (this.fileName) {
        this.src = null
        this.numberOfPages = 0
        let url = this.getAttachments[this.fileName]
        let loadingTask = pdf.createLoadingTask(url)
        this.src = loadingTask
        this.src.promise.then(pdf => {
          this.numberOfPages = pdf.numPages
        })
      }
    }

唉,同样的结果。在控制台中,我看到来自 pdf.worker.js 的以下警告:Warning: TT: invalid function id: 9

不知道这意味着什么。

请问有什么帮助吗?

编辑

我尝试使用 async/await 和 forceUpdate 来做到这一点:

async init() {
      if (this.fileName) {
        this.src = null
        this.numberOfPages = 0
        let url = this.getAttachments[this.fileName]
        let loadingTask = await pdf.createLoadingTask(url)
        await loadingTask.promise.then(pdf => {
          this.src = url
          this.numberOfPages = pdf.numPages
        })
        this.$forceUpdate()
      }
    }

那也没有帮助。但是我发现一旦我更改了传递的文件名,代码确实会转到该init()方法,但由于某种原因它跳过了该loadingTask.promise.then部分,没有进入。我必须知道为什么。

4

1 回答 1

0

好吧,显然 vue-pdf 库存在一些问题。最终我通过在分配 fileName 道具并重新渲染组件时设置超时来解决它:

<PdfViewer v-if="selectedFileName" :fileName="selectedFileName" />
onFileNameSelected(fileName) {
  this.selectedFileName = null
  setTimeout(() => {
    this.selectedFileName = fileName
  }, 0)
}

然后在 PdfViewer 组件中它只是:

created() {
  this.src = pdf.createLoadingTask(this.getAttachments[this.fileName])
},
mounted() {
  this.src.promise.then(pdf => {
    this.numberOfPages = pdf.numPages
  })
}

这对我有用,虽然感觉有点老套。

于 2020-08-11T05:48:00.203 回答