繁体   English   中英

Vue:忽略已定义插槽的插槽包装器

[英]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将被发送到wrapperb-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM