我有一个小加载组件,我希望它的默认文本是‘加载...’。很好的候选插槽,所以我有一个类似下面这样的模板:
<p class="loading"><i class="fa fa-spinner fa-spin"></i><slot>Loading...</slot></p>
这允许我使用例如<loading>Searching...</loading>来更改加载消息。然而,我希望的行为不仅仅是在没有提供插槽内容的情况下显示默认消息,而且在插槽内容为空或空白的情况下也显示默认消息。此时,如果我这样做了,例如<loading>{{loadingMessage}}</loading>和loadingMessage为null,则不会显示任何文本(我希望显示默认文本)。因此,理想情况下,我需要测试this.$slots.default。这将告诉我是否传入了内容,但是如何确定它是否为空?this.$slots.default.text返回undefined。
发布于 2017-11-22 20:08:08
您需要一个用于检查this.$slots的计算属性。对于默认插槽,您将检查this.$slots.default,而对于命名插槽,只需将default替换为插槽名称即可。
computed: {
slotPassed() {
return !!this.$slots.default[0].text.length
}
}然后在你的模板中使用它:
<template>
<div>
<slot v-if="slotPassed">Loading...</slot>
<p v-else>Searching...</p>
</div>
</template>您可以看到一个小示例here。请注意回退内容是如何显示的,而不是“默认内容”,后者位于插槽内。
编辑:我的措辞本可以更好。您需要做的是检查计算值,但是$slots.X属性是a 来检查这一点。你也可以在你的模板中写下插槽检查:
<template>
<div>
<slot v-if="!!$slots.default[0].text">Loading...</slot>
<p v-else>Searching...</p>
</div>
</template>编辑2文本:正如@GoogleMac在评论中指出的,对于无渲染组件(例如<transition>、<keep-alive>等),检查插槽的文本属性失败,因此他们建议的检查是:
!!this.$slots.default && !!this.$slots.default[0]
// or..
!!(this.$slots.default || [])[0]发布于 2020-04-28 23:50:46
@kano的答案很好用,但有一个问题:this.$slots不是反应式的,所以如果它一开始是false,然后变成true,任何computed属性都不会更新。
解决方案是不依赖于computed值,而是依赖created和beforeUpdated (as @MathewSonke points out):
export default {
name: "YourComponentWithDynamicSlot",
data() {
return {
showFooter: false,
showHeader: false,
};
},
created() {
this.setShowSlots();
},
beforeUpdate() {
this.setShowSlots();
},
methods: {
setShowSlots() {
this.showFooter = this.$slots.footer?.[0];
this.showHeader = this.$slots.header?.[0];
},
},
};更新: Vue 3(组合API)
对于Vue 3,检查插槽是否有内容的方法似乎已经改变(使用新的组合API):
import { computed, defineComponent } from "vue";
export default defineComponent({
setup(_, { slots }) {
const showHeader = computed(() => !!slots.header);
return {
showHeader,
};
},
});注意:我找不到任何关于这方面的文档,所以请对它持保留态度,但在我非常有限的测试中似乎是有效的。
https://stackoverflow.com/questions/47432702
复制相似问题