【问题标题】:How to encapsulate parent/child relationship in webcomponents?如何在 webcomponents 中封装父子关系?
【发布时间】:2021-08-04 04:40:45
【问题描述】:

我正在尝试实现具有父/子关系的 web 组件,但我想做的似乎是不可能的。请告诉我我错了!

我正在尝试构建网格布局。我有一个名为grid 的组件和一个名为cell 的组件,一个网格将包含多个子单元格。

我想封装我实现布局的特定方式。我可能会使用 CSS 网格,我可能会使用表格,我可能会在 SVG 中进行所有渲染。我希望行数和列数是网格的属性,而特定的行/列是单元格的属性。

在这种情况下,我使用 CSS 网格,并且使用 Svelte 生成我的 web 组件。我不认为 Svelte 是问题所在,我认为这是 Web 组件工作方式固有的问题。

所以我希望能够写:

<grid rows="3" cols="3">
  <cell row="1" col="1" />
  <cell row="1" col="2" />
  ...
</grid>

我生成的 DOM 在检查器中如下所示:

<grid cols="3" rows="3">
  #shadow-root /* style includes display:grid, columns and rows settings */
  <cell col="1" row="1">
    #shadow-root /* style includes grid-column:1; grid-row:1; */
    <div>...</div>
  </cell>
  <cell col="1" row="2">
    #shadow-root /* style includes grid-column:1; grid-row:2; */
    <div>...</div>  
  </cell>
  ...
</grid>

网格组件具有显示 3x3 网格的所有 CSS 样式。它确实显示了一个网格,但单元格的顺序不正确。

问题是单元格的grid-columngrid-row CSS 属性设置在它们的shadow-root 中并应用于它们的div。具有 display: grid; 作为样式的 HTML 元素的直接子元素是单元格,它们没有 grid-columngrid-row 样式。每个单元格的 shadow-root 下的 div 具有这些样式。所以这些样式会被忽略,单元格会按照它们在 DOM 中出现的顺序排列。

我可以通过使用自己的样式设置行/列来渲染每个单元格来正确布局,如下所示:

<grid rows="3" cols="3">
  <cell style="grid-column:1; grid-row:1" />
  ...
</grid>

但是现在我有一个泄漏的抽象,网格和单元格 web 组件的用户必须知道网格使用 CSS 网格来进行布局,并且必须将 CSS 网格样式应用于单元格以正确放置它们。我想将这个父/子实现细节完全封装在 webcomponents 中。

除非有办法在 web 组件中将 CSS 样式应用于组件本身,在 shadow-root 之上,否则我想要做的似乎是不可能的。这是 Web 组件的固有限制吗?

感谢您的帮助!

【问题讨论】:

    标签: css-grid web-component encapsulation


    【解决方案1】:

    回答我自己的问题:是的,您可以从内部访问 web 组件,向上穿透 shadowRoot。

    在 CSS 中,您可以使用 :host 选择器访问组件。就我而言,我使用 CSS 变量:

    :host {
      grid-column: var(--cell-col);
      grid-row: var(--cell-row);
    }
    

    我仍然需要在 DOM 中设置变量的值,并且在组件的顶级元素(div)中设置它们将不起作用。在 Svelte 中,我可以使用 bind:this 将 div 元素绑定到变量 (topEl)。然后我添加了一个 onMount 处理程序,它从 topEl 向上导航到它的主机,并从 Svelte 组件变量中设置 CSS 变量:

    onMount(() => {
      topEl.parentNode.host.style.cssText += `--cell-col:${col} --cell-row:${row}`
    })
    

    【讨论】:

    • 不要在每个组件上都使用 shadowdom
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多