嵌套的Svelte组件的样式级联(共享)



组件B是作为组件a的slothtml的一部分包含的。下面的代码不像预期的那样工作,因为组件默认不共享样式(svelte-${hash(css)}用于创建一组不同的"虚拟"样式)。(编译期间的命名空间):

// Component A - ./Menu.svelte
<Router>
<ul class="menu">
<Delimiter label={$format('Menu label')}></Delimiter>
{#each routes as route}
{#if route.url?.length > 0}
<li class="menu-item">
<Link to={route.url} getProps={onLinkUpdate}>
{route.title}
</Link>
</li>
{/if}
{/each}
</ul>
</Router>
// Component B - ./Menu/Delimiter.svelte
<li class="divider" data-content={label} {...$$restProps} />

Router和Link是独立包的一部分(因此,考虑作为命名空间a). Delimiter是一个项目级组件(命名空间B).它们都使用相同的样式表,即相同的CSS框架环境。

上面的一个例子被编译成这样:

<ul class="menu">
<li class="divider" data-content="..."></li>
<li class="menu-item">...</li>
</ul>

lidivider类不接受其样式。但是如果Delimiter组件(这一行):

<Delimiter label={$format('Menu label')}></Delimiter>

将被替换为它的直接内容:

<li class="divider" data-content="..."></li>
编译后的源代码如下:
<li class="divider svelte-sipu9k" data-content="..."></li>

所以,问题是——如何正确地"分享"带有外部组件的样式基,这些组件包含(嵌套)到原始名称空间中?(或者这是一个架构问题,我应该尝试不同的方法?)

我将发布我自己的问题的答案,因为,如果我正确理解框架,不应该有任何"级联";在所有。看来最初的问题不在于样式共享。这是一种隐含的"摇树"的结果。类似于CSS代码库。Svelte没有检测到子组件的CSS使用情况(这些样式在父组件中描述,但没有直接在同一个模板中使用,因此它们完全从. CSS输出中删除)。我找到了一些变通方法,如何"级联";适当地样式化到子组件。解决方案,这是为我工作(测试与Svelte 3.*):

方式一(优先)

实际上,应该编写基于组件的样式,而不需要层叠(默认情况下是推荐的)。

。/Delimiter.svelte

<script type="text/javascript">
export let label = '';
</script>
<template src="./Delimiter.html"></template>
<style src="./Delimiter.scss"></style>

。/Delimiter.html

<li class="divider" data-content={label} {...$$restProps} />

。/Delimiter.scss

@import 'spectre.css/src/utilities/divider';

现在,如果你把这个组件作为"嵌套的"第一,它将添加一个额外的svelte-hash类到你的节点,输出.css将包含一组基于名称空间的样式(例如.divider.svelte-n3dv4p)。

的例子:

<li class="divider svelte-n3dv4p" data-content="..."></li>

方式2

这正是我在使用基于组件的框架时想避免的——全局样式。似乎没有(文档?)方法来创建一个"组"。对于嵌套组件,让它们共享几个样式(例如,一个组,包含来自第三方包的一组组件和一个项目级组件)。它是严格的基于组件或"全全局"的;方法(我错了吗?)。

所以,如果你有一个方便的,带有&;global&;的根级组件样式块,可以在这里添加样式,并且在.css输出中不会有svelte-hash类和命名空间后缀。我不太喜欢这种方式,因为它打破了关于组件名称空间和封装的原始想法,但在某些情况下我不得不这样做(当样式是"动态的"时,即编译器无法直接从模板文件中解析它们)。我的一个项目中的一个例子:

/**
* This file represents a set of styles for the application component.
* It also includes global styles (e.g. html, body overrides) and normalization for different browsers.
* Core blocks, elements and modifiers are provided by the Spectre.css framework (https://github.com/picturepan2/spectre).
*/
// managed by Svelte Preprocess using PostCSS (https://github.com/postcss/postcss)
:global {
@import 'spectre.css/src/normalize';
@import 'spectre.css/src/base';
@import 'spectre.css/src/utilities/cursors';
@import '_styles/typography';
// for pages
@import 'spectre.css/src/utilities/position';
@import 'spectre.css/src/icons/icons-core';
@import 'spectre.css/src/icons/icons-navigation';
@import 'spectre.css/src/accordions';
@import 'spectre.css/src/codes';
@import '_styles/layout';
@import '_styles/page';
@import '_styles/github';
}

最新更新