Lit-element - 在另一个组件中导入一个组件,然后访问导入组件的 DOM

Lit-element - Importing a component inside another component and then accessing the DOM of the imported component

老实说,我已经为此绞尽脑汁好几天了。我对 lit-element 和一般的 Web 组件相当陌生。

基本上,我正在构建一个名为 <date-picker> 的新组件,它使用 Flatpickr 插件。此日期选择器组件导入另一个名为 <textfield> 的组件。在该组件内部有一个带有输入字段和图标的包装器(.date-picker)。我需要能够访问包装器,以便我可以单击输入字段和图标来触发日历弹出窗口。但无论我做什么,我都无法到达组件内的那些 dom 元素。我已经尝试使用 this.shadowRoot.querySelector('.date-picker') 和灯光 dom document.querySelector('.date-picker') 以及其他各种方法来访问它们。下面的示例代码。感谢您提供的任何见解。

日期选择器组件:

render() {
  return html`
    <textfield iconalt="Calendar" iconname="calendar" label="Calendar" optionaltext="hide"></textfield>
  `;
}

updated() {
  var datePickerShadow = this.shadowRoot.querySelector('.date-picker'); // gets el in shadow dom
  var datePickerLight = document.querySelector('.date-picker'); // gets el in light dom

  var importantDate = [Date.parse('2021-1-27'), Date.parse('2021-1-5'), Date.parse('2021-2-9')];
    var datePicker = flatpickr(datePickerLight, {
        wrap: true,
        disable: ["2021-01-30", "2021-01-21", "2021-01-08", new Date(2025, 4, 9) ],
        allowInput: true,
        clickOpens: false,
    })
}

如果 <textfield> 是一个自定义元素,那么它的标签名是非法的:自定义元素标签 must contain at least a -. This is probably preventing the browser from upgrading 它(从而呈现它的内容并执行它的逻辑)。

无论如何,如果 .date-picker<textfield> 的模板内,您尝试的 querySelector 调用都不起作用:第一个选择在 <date-picker> 的阴影内dom 但不在子组件中递归,而第二个完全错过阴影 doms.

您可以做的是:

  • 使用级联查询选择器

    class DatePicker extends LitElement {
    
      async firstUpdated() {
        const textField = this.renderRoot.querySelector('text-field');
        await textField.updated; // Wait for first render of text-field
        const datePicker = textField.renderRoot.querySelector('.date-picker');
      }
    
    }
    
  • 如果可能,将 .date-picker 移动到 <date-picker> 的模板中

  • .date-picker 传递给 <text-field>slot

    呈现
    // This way you can directly select .date-picker
    
    render() {
      return html`
        <text-field>
          <div class="date-picker"></div>
        </text-field>
      `;
    }
    
  • <text-field> 中实例化选择器并使用 属性(或通过方法和属性的部分功能)公开实例。

(如果可能我会避免第一个选项)