En Lit, renderRoot
es una propiedad de los componentes que define el punto de montaje en el DOM donde se renderiza el contenido de un componente. Es decir, dónde se colocará el template una vez creada la vista del componente.
Por defecto, renderRoot
se creará en el Shadow DOM del componente, lo que significa que el contenido renderizado dentro de un componente Lit está aislado del resto del DOM de la página, proporcionando encapsulación de estilos y funcionalidad. Esa Encapsulación de Estilos, al usar Shadow DOM (el valor por defecto), hace que los estilos definidos en el componente Lit no afectan al DOM global y viceversa. Esto ayuda a evitar conflictos de estilo.
Puedes hacer una personalización del renderRoot mediante la sobreescritura del método createRenderRoot()
en tu componente. Por ejemplo, si prefieres que el contenido se renderice en el Light DOM (es decir, el DOM regular sin encapsulación), puedes sobrescribir esta función para que devuelva this
:
createRenderRoot() {
return this; // Esto renderizará el componente en el Light DOM
}
Cuando realizas un acceso al renderRoot estás accediendo al marcado de tu componente, por si quieres interactuar con cualquier elemento del template, indepndientemente del punto de montaje de tu componente.
Por tanto, renderRoot
te permite acceder al Shadow DOM (o al Light DOM si lo has sobrescrito) y manipular directamente el contenido renderizado.
Ejemplo de uso de renderRoot
import { LitElement, html, css } from 'lit';
class MyComponent extends LitElement {
static styles = css`
/* Solo un detalle, este componente usamos Shadow DOM (predeterminado), por lo tanto estos estilos se encapsulan */
p {
color: blue;
}
`;
render() {
return html`<p>Hello, Lit!</p>`;
}
firstUpdated() {
// Acceso al renderRoot para realizar manipulaciones directas si es necesario
console.log(this.renderRoot.querySelector('p').textContent);
}
}
customElements.define('my-component', MyComponent);
Ejemplo de uso de renderRoot en el Light DOM
La parte quizás que te puede dar algún problema extra es cuando usas Light DOM como render root, sobre todo cuando accedes al DOM, ya que se hace de otra manera.
En este componente puedes ver un ejemplo que hace más o menos lo del componente anterior durante el firstUpdated
.
import { LitElement, html, css } from 'lit';
class MyLightDomComponent extends LitElement {
static styles = css`
/* En este caso no usamos Shadow DOM, por lo tanto estos estilos NO se encapsulan */
:host {
display: block;
padding: 16px;
background-color: lightgray;
}
.content {
color: blue;
}
`;
// Sobrescribir renderRoot para devolver `this` y usar Light DOM
createRenderRoot() {
return this;
}
render() {
return html`
<div class="content">
Hello, this is rendered in the Light DOM!
</div>
`;
}
firstUpdated() {
// Acceder a la división 'content' para mostrar su textContent en consola
const contentDiv = this.querySelector('.content');
if (contentDiv) {
console.log('Content of the div:', contentDiv.textContent);
}
}
}
customElements.define('my-light-dom-component', MyLightDomComponent);
Con createRenderRoot()
: estamos sobrescribiendo el método createRenderRoot
para devolver this
, de manera que el contenido se renderice en el Light DOM y no en el Shadow DOM.
En el firstUpdated()
estamos accediendo al elemento con la clase .content
usando querySelector
y mostrando su textContent
en la consola.
Dado que el componente se renderiza en el Light DOM, podemos acceder a los elementos con métodos como querySelector
, tal como haríamos con elementos estándar del DOM. Este escenario facilita la manipulación y acceso a los elementos dentro del componente desde fuera o dentro del propio componente.