[英]Vue: wrapper for slots ignoring already-defined slots
Vue 对象有一个非常有用的成员,叫做$attrs
。 $attrs所做的是包含所有未被识别为当前组件的 props 的属性。 $attrs
的一个很好的例子是这里。
我想知道$attrs
是否有$scopedSlots
的等价物。 我目前正在使用类似于https://stackoverflow.com/a/50892881/6100005的第一个建议的方法。 $scopedSlots
的问题是它也传递了已经定义的槽。 要在此处使用该示例:
<template>
<wrapper>
<b-table :foo="foo" v-bind="$attrs" v-on="$listeners">
<template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope"><slot :name="slot" v-bind="scope"/></template>
</b-table>
<slot name="mySlot"></slot>
</wrapper>
</template>
<script>
export default {
props: {
// let's pretend that `b-table` has a prop `foo` that is default `false`
foo: {
type: boolean,
default: true,
}
}
}
</script>
现在,由于$attrs
的行为, foo
不会被绑定两次,但mySlot
将被发送到wrapper
和b-table
。
那么,除了我自己定义的那个,我怎么能把所有的插槽都传下去呢?
我的一个想法是拥有
computed: {
bTableSlots() {
Object.keys(this.$scopedSlots)
.filter( key => key!=='mySlot' )
.reduce( (res, key) => (res[key] = this.$scopedSlots[key], res), {} );
}
}
接着
<template v-for="(_, slot) of bTableSlots" v-slot:[slot]="scope"><slot :name="slot" v-bind="scope"/></template>
想知道是否有更好的方法来做到这一点。 谢谢!
那么除了我自己定义的那个插槽之外,如何传递所有插槽?
为什么这甚至是一个问题? 如果<b-table>
没有名为mySlot
的命名槽,它将忽略它 - 最后它只是组件永远不会访问的$scopedSlots
属性中的另一个条目。 而且因为作用域插槽是作为函数传递的,所以您无需支付任何额外的费用。
当 Vue 编译器看到插槽的内容 ( <template #slotName>
) 时,它将获取内容并将其编译为VNode
Array
或返回VNode
Array
的函数并将其传递给子组件。 您的子组件进一步传递它的事实不会产生任何额外的成本。 它是对现有数组的引用或对现有函数的引用(对于作用域插槽),并且在这两种情况下,如果组件进一步向下不知道具有完全相同名称的插槽,则没有额外成本,除非还有一个进入$scopedSlots
...
如果您觉得这是一个问题,恐怕过滤是唯一的方法 - 您可以按照自己的方式或通过一些辅助数组[ 'slot1', 'slot2' ]
定义所有现有的b-table
插槽并过滤其他所有内容(不是更好的恕我直言,因为每次b-table
添加新插槽时都需要更新组件)....
我理解这个想法并看到与$attrs
的相似之处 - 组件上可能有$unknownSlots
之类的东西来保存当前组件未定义的插槽,但现在 Vue 公共 API 中没有这样的东西......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.