【发布时间】:2020-09-21 05:27:01
【问题描述】:
我希望在 svelte 中创建一个 Spacer 元素。我已经完成了我所设定的,即允许用户将元素包装在<Space></Space> 标签中并传递道具以垂直/水平均匀地间隔它们,甚至将内部元素中心/开始/结束/基线对齐。我遇到的问题是我必须用<SpaceItem></SpaceItem> 将每个子元素包装到<Space></Space> 以获得所需的效果。下面是示例代码:
App.svelte
<script>
import {Space, SpaceItem} from './components/Space';
</script>
<Space>
<SpaceItem>
<Button primary>Primary</Button>
</SpaceItem>
<SpaceItem>
<Button primary icon="add">Primary</Button>
</SpaceItem>
<SpaceItem>
<Button danger>Danger</Button>
</SpaceItem>
</Space>
Space.svelte
<script>
import { SPACE } from './SpaceContext.svelte';
import { setContext } from 'svelte';
import { readable } from 'svelte/store';
export let vertical = false;
export let horizontal = true;
export let alignCenter = false;
export let alignStart = false;
export let alignEnd = false;
export let alignBaseline = false;
export let large = false;
export let middle = false;
export let size = null;
horizontal = vertical ? false : true;
size = size ? size : large ? 24 : middle ? 16 : 8;
const gap = readable(size);
const direction = readable(horizontal ? 'horizontal' : 'vertical');
setContext(SPACE, {
gap,
direction,
});
</script>
<style>
.space {
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
}
.vertical {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
.align-center {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.align-start {
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
}
.align-end {
-webkit-box-align: end;
-ms-flex-align: end;
align-items: flex-end;
}
.align-baseline {
-webkit-box-align: baseline;
-ms-flex-align: baseline;
align-items: baseline;
}
</style>
<div
class="space"
class:horizontal
class:vertical
class:size
class:align-center={alignCenter}
class:align-start={alignStart}
class:align-end={alignEnd}
class:align-baseline={alignBaseline}>
<slot />
</div>
空间项目
<script>
import { SPACE } from './SpaceContext.svelte';
import { getContext } from 'svelte';
const { gap, direction } = getContext(SPACE);
let style;
if ($direction === 'horizontal') {
style = `margin-right: ${$gap}px;`;
} else {
style = `margin-bottom: ${$gap}px;`;
}
</script>
<style>
</style>
<div class="item" {style}>
<slot />
</div>
有没有办法消除<SpaceItem></SpaceItem> 元素并让<Space></Space> 用<SpaceItem></SpaceItem> 包装传递给<slot /> 的每个元素?我只想将所有元素包装在一个 Space 标记中,而不是将每个单独的元素包装在 SpaceItem 标记中。
想要的效果是我能写:
App.svelte
<script>
import {Space, SpaceItem} from './components/Space';
</script>
<Space>
<Button primary>Primary</Button>
<Button primary icon="add">Primary</Button>
<Button danger>Danger</Button>
</Space>
并且仍然在 Space.svelte 文件中使用 <SpaceItem></SpaceItem> 包裹每个按钮。
【问题讨论】:
标签: svelte