在 Svelte 中传递组件列表
Passing a list of components in Svelte
我正在用 svelte 创建一个 Row
组件,它可以容纳任意数量的单元格。
这个有效:
<Row
header
cells={["First", "Second"]}
/>
这样做:
<Row
header
cells={["1", "2", "3", "4"]}
/>
但是,有没有一种方法可以传递自定义组件而不是原始值?以下导致语法错误(我可以在 JSX 中执行此操作):
<Row
header
cells={[<div />, <button />, <span />]}
/>
编辑:
这是我的行代码
<script lang="ts">
export let cells
export let widths
export let header
const sum = widths.reduce((a, b) => a + b, 0)
for (let i = 0; i < widths.length; i++ ){
console.log(widths[i] / sum * 100)
}
</script>
<div class="row" class:header>
{#each cells as cell, i}
<div class="cell" style={`width: ${widths[i] / sum * 100}%`}>
{ cell }
</div>
{/each}
</div>
这就是我想出的“解决方案”。不是最好的,但会满足我的需要。
<script lang="ts">
export let cells
export let widths
// The amount of cells in the
export let header
const sum = widths.reduce((a, b) => a + b, 0)
for (let i = 0; i < widths.length; i++ ){
console.log(widths[i] / sum * 100)
}
</script>
<div class="row" class:header>
<!--
The reason this is like this is because Svelte can't handle dynamic slots,
and doesn't support passing components by reference like in jsx. If we ever need
more columns, then we can just copy and add more. It's just an unrolled for:
-->
{#if widths[0] !== undefined}
<div class="cell" style={`width: ${widths[0] / sum * 100}%`}>
<slot name="0"> </slot>
</div>
{/if}
{#if widths[1] !== undefined}
<div class="cell" style={`width: ${widths[1] / sum * 100}%`}>
<slot name="1"> </slot>
</div>
{/if}
{#if widths[2] !== undefined}
<div class="cell" style={`width: ${widths[2] / sum * 100}%`}>
<slot name="2"> </slot>
</div>
{/if}
// And so on...
<style>
.row {
display: flex;
width: 100%;
border-bottom: 1px solid #ccc;
}
.cell {
padding: 10px;
background-color: white;
}
.header {
font-weight: bold;
}
.cell:nth-child(even) {
background-color: #f7f7f7;
}
</style>
你可以使用<svelte:component>
标签,但你必须换个思路。
将您的单元格想象成这样定义:
interface Cell {
value?: any;
component?: SvelteComponent;
}
那么你的Row
可以这样实现:
<script lang="ts">
export let cells
export let widths
export let header
const sum = widths.reduce((a, b) => a + b, 0)
for (let i = 0; i < widths.length; i++ ){
console.log(widths[i] / sum * 100)
}
</script>
<div class="row" class:header>
{#each cells as cell, i}
<div class="cell" style={`width: ${widths[i] / sum * 100}%`}>
{#if cell.component}
<svelte:component this={cell.component} value={cell.value}/>
{:else}
{cell.value}
{/if}
</div>
{/each}
</div>
我正在用 svelte 创建一个 Row
组件,它可以容纳任意数量的单元格。
这个有效:
<Row
header
cells={["First", "Second"]}
/>
这样做:
<Row
header
cells={["1", "2", "3", "4"]}
/>
但是,有没有一种方法可以传递自定义组件而不是原始值?以下导致语法错误(我可以在 JSX 中执行此操作):
<Row
header
cells={[<div />, <button />, <span />]}
/>
编辑:
这是我的行代码
<script lang="ts">
export let cells
export let widths
export let header
const sum = widths.reduce((a, b) => a + b, 0)
for (let i = 0; i < widths.length; i++ ){
console.log(widths[i] / sum * 100)
}
</script>
<div class="row" class:header>
{#each cells as cell, i}
<div class="cell" style={`width: ${widths[i] / sum * 100}%`}>
{ cell }
</div>
{/each}
</div>
这就是我想出的“解决方案”。不是最好的,但会满足我的需要。
<script lang="ts">
export let cells
export let widths
// The amount of cells in the
export let header
const sum = widths.reduce((a, b) => a + b, 0)
for (let i = 0; i < widths.length; i++ ){
console.log(widths[i] / sum * 100)
}
</script>
<div class="row" class:header>
<!--
The reason this is like this is because Svelte can't handle dynamic slots,
and doesn't support passing components by reference like in jsx. If we ever need
more columns, then we can just copy and add more. It's just an unrolled for:
-->
{#if widths[0] !== undefined}
<div class="cell" style={`width: ${widths[0] / sum * 100}%`}>
<slot name="0"> </slot>
</div>
{/if}
{#if widths[1] !== undefined}
<div class="cell" style={`width: ${widths[1] / sum * 100}%`}>
<slot name="1"> </slot>
</div>
{/if}
{#if widths[2] !== undefined}
<div class="cell" style={`width: ${widths[2] / sum * 100}%`}>
<slot name="2"> </slot>
</div>
{/if}
// And so on...
<style>
.row {
display: flex;
width: 100%;
border-bottom: 1px solid #ccc;
}
.cell {
padding: 10px;
background-color: white;
}
.header {
font-weight: bold;
}
.cell:nth-child(even) {
background-color: #f7f7f7;
}
</style>
你可以使用<svelte:component>
标签,但你必须换个思路。
将您的单元格想象成这样定义:
interface Cell {
value?: any;
component?: SvelteComponent;
}
那么你的Row
可以这样实现:
<script lang="ts">
export let cells
export let widths
export let header
const sum = widths.reduce((a, b) => a + b, 0)
for (let i = 0; i < widths.length; i++ ){
console.log(widths[i] / sum * 100)
}
</script>
<div class="row" class:header>
{#each cells as cell, i}
<div class="cell" style={`width: ${widths[i] / sum * 100}%`}>
{#if cell.component}
<svelte:component this={cell.component} value={cell.value}/>
{:else}
{cell.value}
{/if}
</div>
{/each}
</div>