如何使用嵌套的组件创建和样式化3个自定义元素?

时间:2019-09-05 09:08:57

标签: web-component shadow-dom custom-element svelte svelte-component

我正在尝试在svelte 3中创建custom-element(Web组件)。找不到从CSS设置嵌套组件样式的任何方法。 Svelte会先删除样式,然后再将其注入ShadowDOM中的<style>

问题是我不会在根元素中嵌套组件。 例如:

  • RootComponent(苗条的自定义元素)
    • (导入)FooComponent
    • (导入)BarComponent

如此处所述:svelte-custom-element

所有导入到自定义元素的组件都必须将编译器选项设置为<svelte:options tag="component-name" />

使用此选项集,嵌套的组件可以按预期工作,并被注入根元素的ShadowDOM中。问题在于嵌套组件中定义的styles未被注入。 解决此问题的方法是将它们作为ShadowDom中的全局样式注入到根元素<style>中。 (un)幸运的是,当自定义元素尚不存在时,svelte会自动删除编译期间所有未使用的样式。

我的目标是使用svelte创建Web组件,然后在svelte之外将其用作本机Web组件。

这里是REPL

Conduitry写道,自定义元素在REPL上并不真正起作用:

  

REPL中的编译器选项实际上不会影响正在运行的代码,只会影响显示的代码。因此,启用customElement>并不意味着您正在构建和运行Web组件

因此,与工作示例相比,它更像是一个代码示例。

  1. 我想知道是否还有另一种方法来创建带有嵌套组件和适当样式的苗条自定义元素。
  2. 是否有办法禁止删除未使用的CSS?

https://imgur.com/a/zZia566

<div class="nested">开始从Nested.svelte导入的Nested组件。

<style>元素应该注入了.nested类,但被精巧的编译器删除了。

2 个答案:

答案 0 :(得分:3)

这是因为启用customElement选项时,组件中的每种样式都会注入到自定义元素的shadowRoot中。

class YourComponent extends SvelteElement {
        constructor(options) {
            super();

            this.shadowRoot.innerHTML = `<style>.foo{color:red;}</style>`;
// continues

因此,为了使style出现,您必须使用svelte组件作为自定义元素,而不是使用svelte组件。

您的App.svelte应该如下所示。

<script>
    import Foo from './Foo.svelte'
    import Bar from './Bar.svelte'
</script>
<svelte:options tag="web-component" />

<foo-component/>
<bar-component/>

但是,这都不能解决与自定义元素有关的问题。

  1. :全局选择器不会转换为实际的全局选择器。

  2. 每个嵌套组件都将生成shadowRoot,而大多数情况下,您只需要顶级组件。

从svelte存储库中查看以下与自定义元素相关的问题。

svelte似乎还没有完全支持自定义元素中的样式级联,应该在以后进行处理。

在svelte v3.12.1中进行了检查。

答案 1 :(得分:0)

感谢brunoalano向我发送:svelte-custom-element-template。它使用自定义构建脚本解决了样式问题。