VueJS 组件只有在我在 Vue Devtools 中点击它时才会呈现
VueJS component wont render until I click on it in Vue Devtools
我在博客后端的一个部分(不是 SPA)上使用 VueJS 2.5.3,该部分发出 API 调用以检查附加到 post 的特色图片。
如果找到,它会使用子组件来显示图像。问题是子组件在 API 调用成功后没有渲染,因此图像对象也没有传递给它。
As you can see in this 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>
And here is a link to the code for the parent and child components:
问题出在您的 PostFeaturedImage.vue
组件中。您依赖计算值 processedSrc
来设置数据 属性 showImage
.
但是,showImage
最初是 false
,您在根元素的 v-if
指令中使用它。这意味着 Vue 不会渲染该元素或其中的 <img>
元素。
Vue 中的计算属性是延迟加载的,这意味着它们的函数在被引用之前不会被调用。由于 processedSrc
计算的 属性 仅在 <img>
元素上被引用(并且由于该元素未被渲染)其方法未被调用,这意味着 showImage
属性 永远不会设置为 true
.
但是,当您在 Vue DevTools 中检查组件时,它会列出所有计算属性,这意味着 processedSrc
计算的方法正在被调用,并且 showImage
属性 在这种情况下被设置。
解决您问题的最简单方法是使用 v-show
而不是 v-if
,因为 v-show
中的元素将被隐藏,但即使值为 [=] 仍会呈现15=].
但是,我几乎从不建议根据函数内的逻辑为计算 属性 设置数据 属性 的值。它会产生意想不到的、难以调试的副作用,从而导致您当前遇到的问题。
我建议根据当前在 processedSrc
计算方法中确定其值的逻辑,使您的 showImage
属性 也成为计算的 属性。然后,您可以根据 showImage
.
的值来确定是否尝试计算 processedSrc
的值。
computed: {
showImage: function() {
return this.image && typeof this.image === 'object';
},
processedSrc: function () {
if (this.showImage) {
return this.image.sizes[this.size].file;
}
}
}
通过这种方式,可以更轻松地了解是什么在影响什么,并且您的代码也将更易于维护。
我在博客后端的一个部分(不是 SPA)上使用 VueJS 2.5.3,该部分发出 API 调用以检查附加到 post 的特色图片。
如果找到,它会使用子组件来显示图像。问题是子组件在 API 调用成功后没有渲染,因此图像对象也没有传递给它。
As you can see in this 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>
And here is a link to the code for the parent and child components:
问题出在您的 PostFeaturedImage.vue
组件中。您依赖计算值 processedSrc
来设置数据 属性 showImage
.
但是,showImage
最初是 false
,您在根元素的 v-if
指令中使用它。这意味着 Vue 不会渲染该元素或其中的 <img>
元素。
Vue 中的计算属性是延迟加载的,这意味着它们的函数在被引用之前不会被调用。由于 processedSrc
计算的 属性 仅在 <img>
元素上被引用(并且由于该元素未被渲染)其方法未被调用,这意味着 showImage
属性 永远不会设置为 true
.
但是,当您在 Vue DevTools 中检查组件时,它会列出所有计算属性,这意味着 processedSrc
计算的方法正在被调用,并且 showImage
属性 在这种情况下被设置。
解决您问题的最简单方法是使用 v-show
而不是 v-if
,因为 v-show
中的元素将被隐藏,但即使值为 [=] 仍会呈现15=].
但是,我几乎从不建议根据函数内的逻辑为计算 属性 设置数据 属性 的值。它会产生意想不到的、难以调试的副作用,从而导致您当前遇到的问题。
我建议根据当前在 processedSrc
计算方法中确定其值的逻辑,使您的 showImage
属性 也成为计算的 属性。然后,您可以根据 showImage
.
processedSrc
的值。
computed: {
showImage: function() {
return this.image && typeof this.image === 'object';
},
processedSrc: function () {
if (this.showImage) {
return this.image.sizes[this.size].file;
}
}
}
通过这种方式,可以更轻松地了解是什么在影响什么,并且您的代码也将更易于维护。