【问题标题】:Procedurally generate html elements with Preact and HTM使用 Preact 和 HTM 程序生成 html 元素
【发布时间】:2022-12-11 11:38:21
【问题描述】:

我将 Preact 与 HTM 一起使用(不需要编译器),但在遍历对象并为每个项目创建 DOM 元素时遇到问题。

使用 Preact + HTM 程序生成 DOM 元素的正确方法是什么?

import { h, Component, render } from 'https://unpkg.com/preact?module';
import htm from 'https://unpkg.com/htm?module'; 
const html = htm.bind(h);

function componentValues() {
  var elements = {e1:10, e2:20}; 
  var objEditor = '<div class="row">';
  for (const key in elements) {
    objEditor += '<div class="col">'+key+'</div>';
  }
  objEditor += '</div>';
  return objEditor;
}

function renderPage() {
  render(html`
      <div class="container-xl">
        <p>Hello World</p>
        <${componentValues} />
      </div>`, document.getElementById("app"));
}

renderPage();

我的结果是这样

Hello World

<div class="row"><div class="col">e1</div><div class="col">e2</div></div>

https://codepen.io/28raining/pen/WNyaJrL

【问题讨论】:

    标签: reactjs preact


    【解决方案1】:

    您是想在 JSX 中使用 HTML 字符串,还是想找到最惯用的方式来生成新条目?

    如果是后者(正如您的描述似乎表明的那样),您肯定要避免使用字符串。您可以随意使用 JSX;使用它来模板化您的内容而不是字符串连接。

    尝试这个:

    function componentValues() {
      var elements = {e1:10, e2:20};
      return html`
        <div class="row">
          ${Object.entries(elements).map(([key, value]) =>
            html`<div class="col">${key}</div>`
          )}
        </div>
      `;
    }
    

    如果您确实需要使用 HTML 字符串(它发生了,尽管应该尽可能避免),该字符串不是 JSX 元素/组件,因此您不能将其用作一个。相反,你需要用 html 包装它:

    function renderPage() {
      render(html`
          <div class="container-xl">
            <p>Hello World</p>
            ${html([componentValues()])}
          </div>`, document.getElementById("app"));
    }
    

    标记的模板函数(在本例中为 html)将参数作为数组获取,因此我们创建一个新数组并将 componentValues() 的结果添加到其中。

    【讨论】:

    • 很高兴了解字符串。我正在使用模板,但在尝试字符串时创建了这个问题
    【解决方案2】:

    正如 rschristian 所建议的那样,解决方案是使用数组。 rschristian 的解决方案受限于您允许放入模板字符串的内容。

    function compRow() {
        return html`<div class="row">${componentValues()}</div>`
    }
    
    //Boxes for users to add components
    function componentValues() {
        var elements = state.elements;
        var objEditor = []
        for (const key in elements) {
            objEditor.push(html`<div class="col">${key}</div>`);
        }
        return objEditor;
    }
    

    【讨论】:

    • 在这种情况下,有限是惯用的,因为它的价值。通常惯例是内联,直到复杂性降低它的可口性,此时我们将其移至同一组件内的另一个函数。这允许轻松记住结果。虽然您肯定有一种方法可以在上面工作,但(很可能)大多数开发人员会避免这种方法。