【问题标题】:Vue 3 component does not update on second creationVue 3 组件在第二次创建时不更新
【发布时间】:2021-03-20 08:48:56
【问题描述】:

我有一个自定义的 Vue 组件 ProgressBar,它显示了一个进度条。它正在通过调用setProgress 函数通过父组件进行更新。 组件由父级有条件地渲染。

ProgressBar 组件第一次创建/渲染时,一切都按预期工作,但当它第二次渲染时,尽管data 属性发生了变化,但它不再更新。

摘自父组件:

<ProgressBar
  v-if="downloadInProgress"
  ref="progressBar"
  type="download"
  :onDone="onDownloadFinished"
  :onCancel="onCancel"
  style="width: 80%"
></ProgressBar>

ProgressBar组件

<template>
  <div class="progress-bar-container">
    <div class="progress-bar-label">
      <div style="text-align: left">{{ progressText }}</div>
      <div v-if="cancelable.includes(type)" class="cancel-button">
        <button v-if="!done" class="link" @click="onCancel">Cancel</button>
      </div>
    </div>
    <div class="progress-bar">
      <vue-progress-bar></vue-progress-bar>
    </div>
  </div>
</template>

<script lang="ts">
/* eslint-disable @typescript-eslint/no-explicit-any */

import { defineComponent, PropType } from "vue"

type Actions = "scan" | "download"
const actionText: Record<Actions, string> = {
  scan: "Scanning",
  download: "Downloading",
}

export default defineComponent({
  props: {
    type: {
      type: String as PropType<Actions>,
      required: true,
    },
    onDone: {
      type: Function,
      required: false,
      default: () => {},
    },
    onCancel: {
      type: Function,
      required: false,
      default: () => {},
    },
  },
  data() {
    return {
      total: -1,
      completed: 0,
      errors: 0,
      progress: 0,
      done: false,
      cancelable: ["download"],
      $Progress: this.$Progress as any,
      progressText: "",
    }
  },
  methods: {
    setProgressText() {
      let progressText = [
        `${actionText[this.type]}...`,
        `${this.completed}/${this.total !== -1 ? this.total : "?"}`,
        `${this.errors > 0 ? `(${this.errors} Error(s))` : ""}`,
      ].join(" ")

      if (this.progress === 100) {
        progressText = "Done!"
      }

      this.progressText = progressText
    },
    setProgress(total: number, completed = 0, errors = 0) {
      this.total = total
      this.completed = completed
      this.errors = errors

      if (this.total === 0) {
        // Handle edge case (eg. empty folders)
        this.progress = 100
      } else {
        this.progress = Math.ceil((this.completed / this.total) * 100) || 5
      }

      this.$Progress.set(this.progress)

      if (this.progress === 100) {
        this.done = true
        this.onDone()
      }

      this.setProgressText()
    },
    resetProgress() {
      this.total = -1
      this.completed = 0
      this.errors = 0
      this.progress = 0
      this.done = false

      // Set a small number to make something visible
      this.$Progress.set(5)
    },
  },
  created() {
    this.resetProgress()
    this.setProgressText()
  },
})
</script>

这是我的生命周期方法日志:

尽管$data 对象发生了变化,但显示的progressText 保持不变并呈现默认值“正在下载... 0/?”。 在第一次渲染时一切正常,但在第二次渲染时它停止工作/更新并且文本没有得到更新。

有人知道发生了什么吗?

Vue 版本:3.0.7

编辑:

父组件中更新进度条的代码:

created() {
  const messageListener: browser.runtime.onMessageEvent = async (message: object) => {
    const { command } = message as Message

    if (command === "download-progress") {
      const { completed, total, errors } = message as DownloadProgressMessage
      if (this.progressBarRef) {
        this.progressBarRef.setProgress(total, completed, errors)
      }
    }
  }

  browser.runtime.onMessage.addListener(messageListener)
}

解决方案:

this.progressBarRef 是一个返回 this.$refs.progressBar as any 的计算属性。 删除此计算属性并始终访问 this.$refs.progressBar 直接解决了该问题。 非常感谢@Michal Levý 为我指明了这个方向!

【问题讨论】:

  • 哪种方法不起作用,您只提到了一种更新方法,即调用this.$Progress.set(this.progress),并且在问题的最后,您提到始终有效..您的问题不清楚其他方法用于更新。
  • @MatJ 唯一不起作用的是渲染的progressText 在第二次创建时没有得到更新,尽管setProgress() 函数修改了这个值。我已经尝试将其添加为计算属性或调用$forceUpdate(),但没有任何效果。
  • progressBarRef 是什么?
  • 一个返回this.$refs.progressBar as any的计算属性

标签: vue.js


【解决方案1】:

解决方案:

this.progressBarRef 是一个返回 this.$refs.progressBar as any 的计算属性。 删除此计算属性并始终访问 this.$refs.progressBar 直接解决了该问题。 非常感谢@Michal Levý 为我指明了这个方向!

【讨论】:

    猜你喜欢
    • 2021-07-27
    • 1970-01-01
    • 2023-03-15
    • 2020-01-18
    • 2021-04-28
    • 2017-06-07
    • 2019-06-18
    • 2021-12-09
    • 2012-06-03
    相关资源
    最近更新 更多