在孙组件中使用命名槽

时间:2018-08-27 13:18:21

标签: javascript vue.js vuejs2 vue-component

我创建了一个全局组件,扩展了Bootstrap Vue Table组件,以为名为VTable的每个表创建自定义模板。

Bootstrap Vue Table组件可以使用命名插槽自定义数据呈现。

<template>
  <div>
    <b-table
      :items="items"
      :fields="fields"
      ...
    >
    </b-table>
  </div>
</template>

<script>
  import Table from 'bootstrap-vue/es/components/table/table';

  export default {
    name: 'Vtable',
    extends: Table,
    ...
  };
</script>

我使用新的自定义HTML标记在另一个组件中使用全局表组件。

<v-table
  v-if="items"
  :items="items"
  :fields="fields"
  ...
>
  <template
    slot="timestamp"
    slot-scope="data"
  >
    ...
  </template>
  <template
    slot="row-details"
    slot-scope="row"
  >
    ...
  </template>
</v-table>

问题是VTable组件中使用的命名插槽没有显示在子组件内部。

我还尝试在全局组件内创建一个自定义的命名插槽

<template>
  <div>
    <b-table
      ...
    >
      <slot name="customRendering"/>
    </b-table>
  </div>
</template>

并像使用它

<v-table
  ...
>
  <template slot="customRendering">
    <template
      slot="timestamp"
      slot-scope="data"
    >
      ...
    </template>
    <template
      slot="row-details"
      slot-scope="row"
    >
       ...
    </template>
  </template>
</v-table>

没有成功

这可能是简单地使用在子组件内部定义的命名插槽,还是完全不可能? 我还认为要遍历customRendering插槽值以动态地重新创建Bootstrap Vue表插槽。

1 个答案:

答案 0 :(得分:1)

vtable组件中,您可以定义要传递的插槽。

因此,如果您的组件my-component带有一个子项-> vtable,该子项会扩展-> btable ...

您可以在vtable组件中定义要使用

传递的广告位
<template
  slot="row-details"
  slot-scope="row"
>
    <slot name="row-details"/>
</template>

这是此https://jsfiddle.net/eywraw8t/308324/

的简单示例

您可能需要为每个插槽进行设置。如果要动态地传递所有这些信息(不知道它们的名称),则渲染功能会更好,因为您可以遍历父级发送的所有插槽,然后将它们传递给子级。

docs:https://vuejs.org/v2/guide/render-function.html#Slots

具有渲染功能的组件的示例,该组件将向下传递范围内的插槽

const Bar = Vue.component('vtable', {
  render(h) {
    const children = Object.keys(this.$slots).map(slot => h('template', { slot }, this.$slots[slot]))
    return h('wrapper', [
      h('foo', {
        attrs: this.$attrs,
        on: this.$listeners,
        scopedSlots: this.$scopedSlots,
      }, children)
    ])
  }
});