如何在 Stenciljs 中获取 DOM 元素?

Sma*_*Man 6 javascript stenciljs

import { Component, Prop } from '@stencil/core';
@Component({
    tag: 'my-component',
    styleUrl: 'my-component.css',
    shadow: true
})
export class MyComponent {

  @Prop() first: string;
  @Prop() last: string;
  getElementHere() {
     // how can I get the div here?
  }
  render() {
    return (
      <div>
        Hello, World! I'm {this.first} {this.last}
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我想像在原生 JS 中一样获取 DOM 元素。你如何在 Stencil 中做到这一点?getElementById不起作用。

Squ*_*gle 7

为了扩展 Fernando 的答案,@Element装饰器将组件的根元素绑定到此属性。重要的是要注意这种方法的一些属性:

  1. @Element 绑定属性仅在加载组件后可用 ( componentDidLoad)。
  2. 由于该元素是一个HTML元素的标准,您可以访问元素使用标准的电流分量.querySelector(...).querySelectorAll(...)方法来检索和操纵它们。

这是一个示例,显示元素何时可访问,以及如何操作此元素内的节点(从模板 0.7.24 开始更正):

import { Component, Element } from '@stencil/core';

@Component({
    tag: 'my-component'
})
export class MyComponent {

    @Element() private element: HTMLElement;
    private data: string[];

    constructor() {
        this.data = ['one', 'two', 'three', 'four'];
        console.log(this.element); // outputs undefined
    }

    // child elements will only exist once the component has finished loading
    componentDidLoad() {
        console.log(this.element); // outputs HTMLElement <my-component ...

        // loop over NodeList as per https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
        const list = this.element.querySelectorAll('li.my-list');
        [].forEach.call(list, li => li.style.color = 'red');
    }

    render() {
        return (
            <div class="my-component">
                <ul class="my-list">
                    { this.data.map(count => <li>{count}</li>)}
                </ul>
            </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`componentDidLoad` 限制不是真的(可能在旧版本的 StencilJS 中是真的)。使用 `@Element` 定义的宿主元素可从 `componentWillLoad` 获得。模板中使用 `ref` 定义的其他 DOM 元素仅在组件加载后才可用,即 `componentDidLoad`。 (4认同)
  • @SuriyaKumar,如果是“shadow: true”,则必须通过“this.element.shadowRoot”访问影子 DOM:https://stenciljs.com/docs/styling#things-to-remember-with-shadow-dom (4认同)

Man*_*egi 7

来自官方文档

如果您需要直接引用某个元素(就像通常使用 document.querySelector 所做的那样),您可能需要在 JSX 中使用 ref。

所以在你的情况下:

import { Component, Prop } from '@stencil/core';
@Component({
    tag: 'my-component',
    styleUrl: 'my-component.css',
    shadow: true
})
export class MyComponent {

  @Prop() first: string;
  @Prop() last: string;

  divElement!: HTMLElement; // define a variable for html element

  getElementHere() {
    this.divElement  // this will refer to your <div> element
  }

  render() {
    return (
      <div ref={(el) => this.divElement= el as HTMLElement}> // add a ref here
        Hello, World! I'm {this.first} {this.last}
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)