【问题标题】:Same Vue component twice on same page duplicates component view同一页面上的相同 Vue 组件两次重复组件视图
【发布时间】:2019-08-05 14:01:41
【问题描述】:

所以我正在构建的是一个查看本地 IP 摄像机流的应用程序。我有一个组件通过网络传输 MJPEG 流,然后将它们显示在组件 MJPG.vue 中。这工作得很好,正如我所期望的那样。

我面临的问题是,一旦进入 MJPG.vue,用户可以单击流图像进入辅助“播放”模式,让他们访问记录的数据。所以我需要在回放视图中重用相同的 MJPG.vue 组件。 MJPG.vue 组件的第二个实例行为不正确,并且在某种程度上是第一个实例的精确副本。如果我暂停第一个组件的播放,则第二个组件实例会暂停。如果我暂停第二个实例,则后台的第一个实例会暂停。

这是令人困惑的部分。如果我手动将不同的摄像机流硬编码到第二个组件实例中,这两个组件将相互独立地流式传输并按预期工作。看起来 Vue 重复使用同一个实例两次,而不是组件的每个实例都是自己的。

MJPG.vue

<template>
<img ref="img" :src="img.src" style="border:1px solid white" height=500 width=500 />
</template>

<script>
export default {
  props: {
    camera: {
      type: Object,
      required: true
    },
    aspectRatio: {
      type: Number
    }
  },
  computed: {
    isPlay() {
      return this.$store.state.DVR.isPlay;
    },
    .......
  },
  watch: {
    isPlay(n) {
      n ? this.play() : this.pause();
    },
    img(n, o) {
      if (o.src !== '') {
        // Old img has a real blob url, revoke it to clean up memory.
        URL.revokeObjectURL(o.src); // Must be done for garbage collection, or else memory leaks will form.
      }
      if (n.error === 204) {
        // Image didnt get sent back from the API/Error or problem with image?
        this.errorCount++;
      } else {
        this.errorCount = 0;
        this.setImgSize();
        this.imageBuffer.src = n.src; // Buffer image is so we can determine the real size of the frame received.
      }
    },
    layoutChanged() {
      this.$nextTick(function() {
        this.getWrapperSize();
        this.setImgSize();
      });
    },
    errorCount() {
      // There seems to be some problems with the stream, it could be down. We need to calculate how long to keep checking for images.
      if (this.errorCount * this.framerate >= this.timeout * 1000) {
        this.pause();
        this.streamDown();
      }
    }
  },
  data() {
    return {
      isLoading: true, // If the stream is loading or not.
      display: false, // Used in v-if to show the img to the user.
      img: '', // The src attribute of the image blob(blob:url) the user will see.
      timeout: 15, // Seconds until stream connection error timeout.
      errorCount: 0, // Stream error counter.
      isDown: false, // If the stream is believed to be down.
      backgroundWorker: null, // Background worker that handles the setTimeout lag issues.
      backgroundWorkerGW: null, // Background worker that handles the setTimeout lag issues.
      imageBuffer: new Image(), // Buffer image to collect received image sizes.
      imgHeight: 0, // Height of the image the user will see.
      imgWidth: 0, // Width of the image the user will see.
      imgRatio: null, // Then aspect ratio of the imageBuffer, used to calculate image size for its container.
      wrapperHeight: 0, // Wrapper div height.
      wrapperWidth: 0, // Wrapper div width.
      showOverflowOnActual: false, // Should the scrollbars be displayed on the image? Used for Actual image size setting.
      framerate: 0 // The framerate that the API is getting new images.
    };
  },
  mounted() {
      // Do some stream setup here...
  },
  methods: {
      // Streaming functions here...
  }
</script>

<style scoped>
.....
</style>

【问题讨论】:

  • 您依靠vuex 的全局状态来确定播放DVR 的时间。您已经附加了一个观察者来观察该变量的变化,并且每个组件都会对此做出反应。
  • @Ohgodwhy 所以任何对组件内部 $store 的引用都会在同一组件的所有实例上触发这种可观察性重复?
  • 是的。他们都在关注同一个变量。考虑在商店中为每个 DVR 使用唯一变量。
  • @Ohgodwhy 所以在 MJPG.vue 我删除了所有对 Vuex($store) 的引用,它仍然是相同的行为。

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

评论没有足够的声誉;)

如果是同一个实例问题,尝试设置 unqiue 键,例如:

<component :key="something1" :is="stream" />
<component :key="something2" :is="stream" />

喜欢这里的建议:v-bind:key="question.id"

【讨论】:

  • 我也试过了,但没有解决我面临的问题。
  • 是否有可能您没有通过切换播放来更改组件状态,而是流本身?暂停?所以你使用了组件的两个实例,但使用了流的一个实例?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
  • 2016-11-18
  • 2022-01-16
  • 2018-01-04
  • 1970-01-01
相关资源
最近更新 更多