关于Vue3和插槽,我有一个非常具体的问题,我已经为可重用的表创建了以下组件.

FSTable.vue

<template>
  <table>
    <thead>
      <slot renderAs="header"></slot>
    </thead>
    <tbody>
      <tr v-for="(row, index) of rows" :key="index">
        <slot renderAs="cell" :row="row"></slot>
      </tr>
    </tbody>
  </table>
</template>

<script setup lang="ts">
  const rows = [{
    name: "Row 1",
    col2: "XX",
    col3: "YY"
  },
  {
    name: "Row 2",
    col2: "XX",
    col3: "YY"
  },
  {
    name: "Row 3",
    col2: "XX",
    col3: "YY"
  }];
</script>

FSTableColumn.vue

<template>
  <th v-if="props.renderAs === 'header'" class="p-2">
    <slot name="header" :header="props.header">
      {{ props.header }}
    </slot>
  </th>
  <td v-else-if="props.renderAs === 'cell'" class="p-2">
    <slot :value="props.property ? row[props.property] : row">
      {{ props.property ? row[props.property] : "" }}
    </slot>
  </td>
</template>

<script setup lang="ts">
  const props = defineProps<{
    renderAs?: string;
    header?: string;
    property?: string;
    row?: any;
  }>();
</script>

如您所见,FSTableColumn被呈现为标题或单元格.

Usage

<FSTable v-slot="slotProps">
  <FSTableColumn v-bind="slotProps" header="Column 1" property="name" v-slot="cellProps">
    <!-- This column renders a custom cell -->
    CustomCell: {{ cellProps.value }}
  </FSTableColumn>
  <FSTableColumn v-bind="slotProps" header="Column 2" property="col2">
    <!-- This column renders the default cell -->
  </FSTableColumn>
  <FSTableColumn v-bind="slotProps" header="Column 3" property="col3">
    <!-- This column renders a custom header -->
    <template #header="headerProps">
      CustomHeader: {{ headerProps.header }}
    </template>
  </FSTableColumn>
</FSTable>

Question 正如你所看到的,我需要从FSTableFSTableColumn传递slotProps. 有没有可能go 掉这个并隐式地传递它们?

推荐答案

只需使用表中的功能组件自动将槽props 添加到柱子中:

VUE SFC PLAYGROUND

<script setup>
  const rows = [{
    name: "Row 1",
    col2: "XX",
    col3: "YY"
  },
  {
    name: "Row 2",
    col2: "XX",
    col3: "YY"
  },
  {
    name: "Row 3",
    col2: "XX",
    col3: "YY"
  }];

import { useSlots } from 'vue';

const slots = useSlots();

const renderCols = props => {

  const cols = slots.default();
  cols.forEach(vnode => Object.assign(vnode.props ??= {}, props));
  return cols;

};
</script>


<template>
  <table>
    <thead>
      <render-cols renderAs="header"/>
    </thead>
    <tbody>
      <tr v-for="(row, index) of rows" :key="index">
        <render-cols renderAs="cell" :row="row"/>
      </tr>
    </tbody>
  </table>
</template>

用法:

<script setup>
import FSTable from './FSTable.vue';
import FSTableColumn from './FSTableColumn.vue';
import { ref } from 'vue'

const msg = ref('Hello World!')
</script>

<template>
<FSTable>
  <FSTableColumn header="Column 1" property="name" v-slot="cellProps">
    <!-- This column renders a custom cell -->
    CustomCell: {{ cellProps.value }}
  </FSTableColumn>
  <FSTableColumn header="Column 2" property="col2">
    <!-- This column renders the default cell -->
  </FSTableColumn>
  <FSTableColumn header="Column 3" property="col3">
    <!-- This column renders a custom header -->
    <template #header="headerProps">
      CustomHeader: {{ headerProps.header }}
    </template>
  </FSTableColumn>
</FSTable>
</template>

Vue.js相关问答推荐

Vue CDN的html工作,但v—如果不工作

Vue3组合-如何在组件卸载时注销回调

V-img不显示文件夹中的图像

如何在Vue3中使用vuechartjs 5.2从父组件更新图表

有没有办法将react 键作为值传递给由 v-for 创建的 v-model

vuejs3 youtube-plugin YT 未定义控制台错误

如何 for each 动态创建的按钮/文本字段设置唯一变量?

指定一个 vue-cli vue.config.js 位置

在 Vue.js 中动态挂载单个文件组件

如何为 Vue 应用提供 robots.txt

重新加载发布到 Github 页面的 Vue 网站时出现 404

Vue.js 如果在视图中

在 Vuejs 中计算 DOM 元素之间距离的最佳方法是什么?

v-for 如何在继续之前判断未定义的列表

为 Vue 组件动态添加属性

Leaflet+Vue+Vuetify / Leaflet map 隐藏 vuetify 弹出对话框

Vuejs css 范围性能

vuex 是 state.array.push react式的吗?

在 Vuejs 中放置 firebase.auth().onAuthStateChanged() 的位置

带有 Google Auth Signin 的 Vuejs 全局函数