lit-html 的动态标签不可能?

cod*_*leb 7 javascript web-component custom-element lit-element lit-html

谁能告诉我为什么我不能在 lit-html 的html方法中使用变量?

const h1 = 'h1';
return html`
  <${h1} class="a-heading ${classes}">
    <slot></slot>
  </${h1}>
`;
Run Code Online (Sandbox Code Playgroud)

如果我替换${h1}h1没有问题的作品。

Gh6*_*h61 11

现在是 2022 年,解决方案已经存在(从 2020 年底 -问题)。

现在您可以使用https://lit.dev/docs/templates/expressions/#static-expressions中的内容

  1. 对于您可以控制的字符串文字,请使用literal模板。

    您必须导入特殊版本的模板html并使用该literal模板。

import {html, literal} from 'lit/static-html.js';

@customElement('my-button')
class MyButton extends LitElement {
  tag = literal`button`;
  activeAttribute = literal`active`;
  @property() caption = 'Hello static';
  @property({type: Boolean}) active = false;

  render() {
    return html`
      <${this.tag} ${this.activeAttribute}?=${this.active}>
        <p>${this.caption}</p>
      </${this.tag}>`;
  }
}
Run Code Online (Sandbox Code Playgroud)

进而

@customElement('my-anchor')
class MyAnchor extends MyButton {
  tag = literal`a`;
}
Run Code Online (Sandbox Code Playgroud)
  1. 对于无法使用 装饰的东西literal,您可以使用unsafeStatic.

    同样,您必须导入特殊版本的函数html然后使用unsafeStatic该函数。

import {html, unsafeStatic} from 'lit/static-html.js';

@customElement('my-button')
class MyButton extends LitElement {
  @property() caption = 'Hello static';
  @property({type: Boolean}) active = false;

  render() {
    // These strings MUST be trusted, otherwise this is an XSS vulnerability
    const tag = getTagName();
    const activeAttribute = getActiveAttribute();
    return html`
      <${unsafeStatic(tag)} ${unsafeStatic(activeAttribute)}?=${this.active}>
        <p>${this.caption}</p>
      </${unsafeStatic(tag)}>`;
  }
}
Run Code Online (Sandbox Code Playgroud)


cod*_*leb 6

对于对我的解决方案感兴趣的每个人:unsafeHTML如果可以,请使用(如果您在其中包含任何输入字段,则不应这样做)。

    import { unsafeHTML } from 'lit-html/directives/unsafe-html';
   
     // ...

    const template = `
      <h${this.rank} class="a-heading">
        <slot></slot>
      </h${this.rank}>
    `;

    return html`
      ${unsafeHTML(template)}
    `;
Run Code Online (Sandbox Code Playgroud)


Jus*_*ani 5

lit-html不允许动态标记名称的原因是 lit-html 的工作原理是用特殊标记替换表达式,然后<template>用结果创建一个 HTML元素。

关键,稍有含蓄,这里的部分是,它并没有使用这些值来创建模板。在模板被克隆之后,它们被插入到模板中,也就是在 HTML 被解析之后。没有办法进入 DOM 树并更改一个元素的标签名称。我们必须移除元素,替换它,设置任何绑定,并将所有子元素移动到新元素中。这将是非常昂贵的。

我们确实计划支持创建 HTML之前插入的静态绑定(一旦我们可以放弃对不能完全正确实现模板文字的旧版 Edge 浏览器的支持)<template>,这将允许使用标记名称的表达式。然而,静态绑定不能用新数据更新——模板创建时的值是唯一使用的值。