Class Svelte 中自定义组件的样式未注册

Class styling on a custom component in Svelte does not register

我正在使用 Svelte/Sapper 模板并添加了景点 UI,但我无法将任何 class/styles 应用于他们的自定义组件,如下所示:

<TextField class='search-box' type='search' />
<style>
    .search-box {
        margin-bottom: 10px;
    }
</style>

我明白了

Unused CSS selector ".search-box"

到目前为止,让它对我有用的唯一方法是在样式上应用 :global 修饰符。

这里的问题是 Svelte 无法知道 class 属性 指的是 CSS class 甚至 where 应用此 class。需要注意的是,以下都是有效的 Svelte 组件:

<span>Hello World</span>
<span>Hello</span>
<span>World</span>
Hello World

在第一个例子中,它应该可能在跨度上,但是在第二个例子中,class应该去哪里,第一个或第二个跨度?或者两者都有?最后一个根本没有 DOM 元素的示例又如何呢,您不能将 class 添加到文本节点。

因此,您的 class 被 Svelte 标记为 未使用 并在编译期间被删除。这符合 Svelte 单一文件组件 理念,其中组件的所有样式都包含在同一个文件中。虽然您的构造与它有时是一种有效的方法相反,但这就是 :global 的用途。

请注意,您可以从 TextField 导出 class 属性 并应用于您选择的元素,但您仍然需要将 class 标记为全局:

<script>
    // You have to this because class is a reserved keyword in JavaScript
    let className;
    export { className as class };
</script>
<div>
  <p>
    <span class={className}>...</span>
  <p>
  <button>...</button>
</div>

我相信您想要实现的目标目前在 Svelte 中是不可能的。 class prop 在 Svelte 中不被视为特殊属性,因此它不会将样式范围泄漏到子组件中,特别是因为子组件中不必有一个根元素(与 Vue.js,例如)。

因此,您不能在父组件中添加样式并期望它们到达子组件。您唯一的选择是使用 :global 修饰符或将样式添加到全局样式表(直接包含在 HTML 中,而不是 Svelte 组件中)

请注意,您可以组合使用 :global 和范围样式。例如,考虑:

<div class='local'>
    <TextField class='search-box' type='search' />
</div>

<style>
    .local :global(.search-box) {
        margin-bottom: 10px;
    }
</style>

这样,样式就不会泄漏到其他组件,并且仍然仅限于此组件。