问题描述
我正在使用 svelte/Sapper templae 并添加了 Attractions UI,但我无法将任何类/样式应用于它们的自定义组件,如下所示:
<TextField class='search-Box' type='search' />
<style>
.search-Box {
margin-bottom: 10px;
}
</style>
我明白
未使用的 CSS 选择器“.search-Box”
到目前为止,对我来说让它起作用的唯一方法是在样式上应用 :global
修饰符。
解决方法
这里的问题是 Svelte 无法知道 class
属性在此处或什至 何处引用了一个 CSS 类来应用该类。需要注意的是,以下都是有效的 Svelte 组件:
<span>Hello World</span>
<span>Hello</span>
<span>World</span>
Hello World
在第一个示例中,它应该可能在跨度上,但是在第二个示例中,类应该放在第一个还是第二个跨度上?或者两者都有?那么最后一个完全没有 DOM 元素的例子呢,你不能向 textnode 添加一个类。
因此,您的类被 Svelte 标记为 unused 并在编译期间删除。这符合 Svelte 单个文件组件 的理念,其中一个组件的所有样式都包含在同一个文件中。虽然您的构造与它有时是一种有效的方法背道而驰,但这就是 :global
的用途。
请注意,您可以从 TextField 导出 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
属性在 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>
这样,样式就不会泄露给其他组件,并且仍然只作用于这个组件。