v-if条件未从计算的属性更新

时间:2020-09-11 21:28:09

标签: javascript vue.js vuejs2 vuex

已解决(几乎):删除<div v-if="isFrameLoaded">并将src数据绑定到<video>。现在,它在发送请求的同时加载(getBLOB中没有数据,但随后重新加载自身(无需手动保存文件)。 为什么这个特定的v-if对我不起作用仍然是一个谜。谢谢大家!。

编辑了 Frame.vue

      //This is needed
<video v-bind:src="getBLOB"> 
           //Here too
    <source v-bind:src="getBLOB" type="video/mp4" />
    Your browser does not support the
</video>

编辑:

state: {
...,
isFrameLoaded: false
}

商店content.js中的信件

getters:{
...,
isFrameLoaded: state => state.isFrameLoaded
}

变异

mutations: {
...,
SAVE_ISFRAMELOADED(state, boolean) {
      state.isFrameLoaded = boolean;
      console.log("frame loaded");
    },
}

我尝试过的事情: 绑定:keythis.$forceUpdate()<keep-alive>


问题是在下载资源(<div v-if="isFrameLoaded">)之前检查isFrameLoaded == false,一段时间后将下载资源,并且应返回计算的属性 在 $ store.getters 中为true,但是我看到的是,即使更新了状态后,该计算属性也不会再被调用。

我以前做过,并且按预期工作。唯一的区别是, Home.vue 是视图, Frame.vue 是组件, $ store 有效。

这不起作用 Frame.vue

<template>
...
    <div v-if="isFrameLoaded">
        <video>
           <source v-bind:src="getBLOB" type="video/mp4" />
        </video>
    </div>
</template>
<script>
export default {
  computed: {
    isFrameLoaded() {
    //this is called just once
      console.log("isFrameLoaded()");
      return this.$store.getters["content/isFrameLoaded"];
    }
  }
};
</script>

这有效 Home.vue ,“列表”是一个组件。vue


<template>
...
    <template v-if="childDataLoaded">
        <list />
    </template>
</template>
<script>
export default {
  name: "Home",
  computed: {
    childDataLoaded() {
      return this.$store.getters["content/isThumbnailLoaded"];
    }
    }
  
};
</script>

这是修改 isFrameLoaded 的地方 contentstore.js

getFrameBlob({ commit, state }) {
      commit("SAVE_ISFRAMELOADED", false); //HERE
      return contentService
        .getBigImg()
        .then(response => {
          var url = URL.createObjectURL(
            new Blob([response.data], { type: state.frame.mediaType })
          );
          commit("SAVE_CURRENTBLOB", url);
          commit("SAVE_ISFRAMELOADED", true); //HERE
          return url;
        });
    },

并且此方法修改了有效的条件( isThumbnailLoaded

getThumbnails({ commit, state }) {
      commit("SAVE_ISTHUMBNAILLOADED", false); //HERE
      state.home.imgs.forEach((thumbnail, i) => {
        contentService
          .getThumbImg()
          .then(response => {
            var url = URL.createObjectURL(new Blob([response.data]));
            commit("SAVE_THUMBFRAME", {
              key: state.home.frames[i],
              value: url,
              like: state.home.likes[i]
            });
            if (state.thumbFrame.length == state.home.imgs.length) {
              commit("SAVE_ISTHUMBNAILLOADED", true); //HERE
            }
          });
      });
      return;

我注意到,如果我从 Frame.vue 中删除v-if,则在初次尝试时不会加载其源(图像类型始终加载,而视频类型则不加载),但是如果我更新并现在,在项目运行时保存该项目。

所以。。有什么提示吗?我读到有关nextTick()函数的信息,但它似乎太复杂了,我也很好奇为什么在运行项目时修改项目文件可以解决该问题。

谢谢!

1 个答案:

答案 0 :(得分:0)

您实际上不需要创建计算属性。商店吸气剂已经是反应性的。

将吸气剂包装在计算的prop中的方式不会使计算的prop具有反应性,因为getter就像计算的属性实际上是在引用时隐式执行的方法。如果您实际上记录了计算的道具,例如:

console.log('Getter: ', this.$store.getters["content/isThumbnailLoaded"]);

您将看到这将记录一个方法,而不是您期望的值。

您可以使用mapGetters将您的吸气剂映射到组件中的计算道具。

import { mapGetters } from 'vuex';

  export default {
    computed: {
      ...mapGetters({
        isFrameLoaded: 'content/isFrameLoaded',
      }),
    }
  };

或者如果您想继续使用这种方法,则可以执行以下操作:

export default {
  computed: {
    isFrameLoaded() {
      //this is called just once
      console.log("isFrameLoaded: ", this.$store.getters["content/isFrameLoaded"]());
      return this.$store.getters["content/isFrameLoaded"]();
    }
  }
};

我仍然建议使用第一种方法,该方法更易读和更干净。

致谢。