使用Preact+HTM(无编译器)程序化生成DOM元素的正确方法
Preact+HTM程序化生成DOM元素的正确方式
问题描述
我正在使用无需编译器的Preact与HTM,遍历对象创建DOM元素时遇到问题——当前代码输出HTML字符串而非实际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>
解决方案
核心问题是你在componentValues中拼接HTML字符串返回,但Preact+HTM需要的是虚拟DOM节点而非纯字符串。正确做法是利用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() { const elements = {e1:10, e2:20}; // 遍历对象键名,生成每个col对应的虚拟DOM节点数组 const colElements = Object.keys(elements).map(key => { return html`<div class="col">${key}</div>`; }); // 用HTM模板包裹父容器,嵌入子元素数组 return html`<div class="row">${colElements}</div>`; } function renderPage() { render(html` <div class="container-xl"> <p>Hello World</p> <${componentValues} /> </div>`, document.getElementById("app")); } renderPage();
关键说明
- HTM的
html模板函数会自动将模板内容转换为Preact可识别的虚拟DOM节点,而非普通字符串 - 在模板中使用
${colElements}时,HTM会自动展开数组内的虚拟DOM节点,将它们作为父元素的子节点渲染 - 禁止手动拼接HTML字符串,这类字符串会被Preact当作普通文本输出,不会被解析为DOM元素
内容的提问来源于stack exchange,提问作者Tock
相关产品推荐
相关产品推荐

