Vue.js 仅显示包含内容的插槽
是否有一种方法仅在插槽有任何内容时显示它 例如,我正在构建一个简单的Vue.js 仅显示包含内容的插槽,vue.js,vuejs2,Vue.js,Vuejs2,是否有一种方法仅在插槽有任何内容时显示它 例如,我正在构建一个简单的Card.vue组件,我只希望在页脚插槽包含以下内容时显示页脚: 模板: <template> <div class="panel" :class="panelType"> <div class="panel-heading"> <h3 class="panel-title"> <slot nam
Card.vue
组件,我只希望在页脚插槽包含以下内容时显示页脚:
模板:
<template>
<div class="panel" :class="panelType">
<div class="panel-heading">
<h3 class="panel-title">
<slot name="title">
Default Title
</slot>
</h3>
</div>
<div class="panel-body">
<slot name="body"></slot>
<p class="category">
<slot name="category"></slot>
</p>
</div>
<div class="panel-footer" v-if="hasFooterSlot">
<slot name="footer"></slot>
</div>
</div>
</template>
默认标题
脚本:
<script>
export default {
props: {
active: true,
type: {
type: String,
default: 'default',
},
},
computed: {
panelType() {
return `panel-${this.type}`;
},
hasFooterSlot() {
return this.$slots['footer']
}
}
}
</script>
导出默认值{
道具:{
主动:对,
类型:{
类型:字符串,
默认值:“默认值”,
},
},
计算:{
panelType(){
返回`panel-${this.type}`;
},
hasFooterSlot(){
返回此。$slots['footer']
}
}
}
鉴于:
<card type="success"></card>
因为上面的组件不包含页脚,所以不应该呈现它,但它是
我尝试使用this.$slots['footer']
,但它返回未定义的值
有人有什么建议吗?应该在
this.$slots.footer
所以,这应该行得通
hasFooterSlot() {
return !!this.$slots.footer
}
.您应该检查
vm.$slots
以及vm.$scopedSlots
hasSlot (name = 'default') {
return !!this.$slots[ name ] || !!this.$scopedSlots[ name ];
}
我也遇到过类似的问题,但在广泛的代码库中,当创建原子设计结构化组件时,总是要编写
hasSlot()
方法,而当涉及到TDD时,这又是一个需要测试的方法。。。尽管如此,您始终可以将原始逻辑放在v-if
中,但我发现模板最终会变得杂乱无章,有时更难阅读,特别是对于检查代码结构的新开发人员
我的任务是找到一种方法,在插槽未提供时删除插槽的父div
s
问题:
//实例化
向我展示
//呈现
向我展示
希望我能正确理解这一点。如果插槽为空,为什么不使用未呈现的
标记呢
<slot name="foo"></slot>
像这样使用它:
<template slot="foo">
...
</template>
...
简而言之,在内联中执行此操作:
<template lang="pug">
div
h2(v-if="$slots.title")
slot(name="title")
h3(v-if="$slots['sub-title']")
slot(name="sub-title")
</template>
div
h2(v-if=“$slots.title”)
插槽(name=“title”)
h3(v-if=“$slots['sub-title']”)
插槽(名称=“子标题”)
起初我认为它是有效的,但我不得不对它进行一些扩展,因为$scopeSlots返回一个函数,无论其返回值如何,该函数总是真实的。这是我的解决方案,尽管我已经得出结论,这个问题的真正答案是“这样做是一种反模式,如果可能的话,你应该避免这样做”。例如,只需制作一个单独的页脚组件,可以插入其中
黑胶溶液
最佳实践(页脚的帮助器组件)
const panelComponent={
模板:`
`
}
常量页脚组件={
模板:`
`
}
var app=新的Vue({
el:“#应用程序”,
组成部分:{
面板组件,
页脚组件
},
数据(){
返回{
名称:“Vue”
}
}
})
。漂亮的面板{
最大宽度:200px;
边框:1px实心浅灰色;
}
.漂亮的面板内容{
填充:30px;
}
.漂亮的面板页脚{
背景颜色:浅灰色;
填充:5px30px;
文本对齐:居中;
}
带页脚的面板
乱数假文
一些页脚内容
无页脚面板
乱数假文
CSS大大简化了这一点。只要使用下面的代码,瞧
.panel-footer:empty {
display: none;
}
这是Vue 3合成API的解决方案:
从“vue”导入{ref};
导出默认值{
设置(道具,{slots}){
const Hastintle=ref(假)
//按名称检查插槽是否存在,是否有内容。
//如果为空,则返回一个空数组。
if(slots.title&&slots.title().length){
hasttle.value=true
}
返回{
黑斯特尔
}
}
}
有效!抱歉,这是我的错,在将内容输入插槽时使用了错误的语法。谢谢!!:)this.$slots.footer
和this.$slots['footer']
是等价的,不是吗?这真的是解决方案还是出了什么问题?@DanielBeck你是对的,他们都指向同一件事。如果没有内容,两者都将返回undefined。唯一不同的是我返回一个布尔值,但是,测试它时,从hasFooterSlot返回undefined将导致v-if隐藏组件。。因此,从技术上讲,我认为您的代码应该是有效的。(澄清一下,我不是最初的询问者,只是一个感兴趣的观察者:)这似乎在Vue 2.6中的所有情况下都不起作用-当其他$ScopeDSlot存在时,错误地返回false(至少在某些情况下,例如从dom中删除并通过v-if
添加回来的元素)但是这是。$scopedSlots[name]
返回一个渲染函数,而不是像vm那样的vNode数组。$slots
执行。因此,最后它强制为布尔值true。我的this。$slots
是一个空对象,this。$scopedSlots
帮助我。有关考虑到$scopeSlots[name]
是一个函数(Vue 2.1.0+)的答案,请参阅太棒了!谢谢!问题是当您希望外部元素包装插槽时,但不希望在插槽未给定或为空时渲染外部元素。这无法解决用例问题。这很酷,但由于各种边缘情况、scopedSlots、默认插槽内部内容(名为slot)而存在下滑s、 等等;依我的拙见,包装槽似乎是一种反模式,也许最好问问我
.panel-footer:empty {
display: none;
}