7

我在博客后端的一个部分(不是 SPA)上使用 VueJS 2.5.3,该部分进行 API 调用以检查附加到帖子的特色图像。

如果找到,它会使用一个子组件来显示图像。问题是 API 调用成功后子组件没有渲染,因此图像对象也没有传递给它。

正如你在这个 GIF 中看到的,子组件没有渲染<!---->,我有一个v-if检查图像是否存在。但是,如果我单击 Vue DevTools 内的子组件,子组件会按预期呈现并显示图像。

我的问题是为什么只有在 Vue Devtools 中单击子组件后才会呈现子组件?当您单击组件时,Vue Devtools 是否会触发某种事件?

这是子组件:

<template>
    <div v-if="showImage" class="featured-image-container" :class="[ size ]">
        <img :src="processedSrc" alt="Featured Image">
    </div>
</template>

<script>
export default {
    props: {
        image: {
            type: Object
        },
        size: {
            type: String,
            required: true
        }
    },
    data () {
        return {
            showImage: false
        }
    },
    computed: {
        processedSrc: function () {
            if (this.image && typeof this.image === 'object') {
                this.showImage = true
                return this.image.sizes[this.size].file
            } else {
                this.showImage = false
            }
        }
    }
}
</script>

这是父组件和子组件的代码链接:

4

1 回答 1

12

问题出在您的PostFeaturedImage.vue组件中。您依赖于计算值processedSrc来设置数据属性showImage

但是,showImage最初是在根元素false的指令中使用它。v-if这意味着 Vue 不会渲染该元素或其中的<img>元素。

Vue 中的计算属性是延迟加载的,这意味着它们的函数在被引用之前不会被调用。由于processedSrc计算属性仅在<img>元素上被引用(并且由于该元素没有被渲染),因此它的方法没有被调用,这意味着该showImage属性永远不会设置为true.

但是,当您在 Vue DevTools 中检查一个组件时,它会列出所有计算属性,这意味着计算的方法processedSrc正在被调用,并且showImage在这种情况下属性正在被设置。


解决您的问题的最简单方法是使用,v-show而不是v-if,因为 a 中的元素v-show将被隐藏,但即使值为false.

但是,我几乎从不建议根据计算属性的函数中的逻辑来设置数据属性的值。它会产生意想不到的、难以调试的副作用,从而导致您当前遇到的问题。

我建议根据当前在计算方法showImage中确定其值的逻辑,将您的属性也设为计算属性。processedSrc然后,您可以根据 的值来决定是否尝试计算processedSrccomputed 的值showImage

computed: {
  showImage: function() {
    return this.image && typeof this.image === 'object';
  },
  processedSrc: function () {
    if (this.showImage) {
      return this.image.sizes[this.size].file;
    }
  }
}

这样,更容易看到是什么影响了什么,您的代码也更容易维护。

于 2017-11-06T22:08:37.790 回答