HTM 学习笔记
htm
使用标准标记模板的 JSX 替代方案
官方资料
- website: https://www.npmjs.com/
- Github: https://github.com/developit/htm
安装
htm 已发布到 npm,可通过 unpkg.com CDN 访问:
通过 npm:
npm i htm
从 unpkg 热链接:( 无需构建工具!)
import htm from 'https://unpkg.com/htm?module'
const html = htm.bind(React.createElement);
// just want htm + preact in a single file? there's a highly-optimized version of that:
import { html, render } from 'https://unpkg.com/htm/preact/standalone.module.js'
用法
如果您使用的是 Preact 或 React,我们提供了现成的绑定,使您的生活更轻松。它们还具有在所有模块之间共享模板缓存的附加好处。
import { render } from 'preact';
import { html } from 'htm/preact';
render(html`<a href="/">Hello!</a>`, document.body);
同样,对于 React:
import ReactDOM from 'react-dom';
import { html } from 'htm/react';
ReactDOM.render(html`<a href="/">Hello!</a>`, document.body);
高级用法
由于 htm 是一个通用库,我们需要告诉它将模板“编译”到的内容。您可以绑定 htm 到任何形式的函数 h(type, props, …children) (hyperscript)。此函数可以返回任何内容 - htm 从不看返回值。
这是一个 h() 返回树节点的示例函数:
function h(type, props, ...children) {
return { type, props, children };
}
要使用我们的自定义 h() 函数,我们需要 html 通过绑定 htm 到我们的 h() 函数来创建自己的标记函数:
import htm from 'htm';
const html = htm.bind(h);
const html = htm。绑定(h); 现在,我们有了一个 html() 模板标记,可用于生成上面创建的格式的对象。
这是为了清楚起见:
import htm from 'htm';
function h(type, props, ...children) {
return { type, props, children };
}
const html = htm.bind(h);
console.log( html`<h1 id=hello>Hello world!</h1>` );
// {
// type: 'h1',
// props: { id: 'hello' },
// children: ['Hello world!']
// }
如果模板在根级别具有多个元素,则输出为 h 结果数组:
console.log(html`
<h1 id=hello>Hello</h1>
<div class=world>World!</div>
`);
// [
// {
// type: 'h1',
// props: { id: 'hello' },
// children: ['Hello']
// },
// {
// type: 'div',
// props: { class: 'world' },
// children: ['world!']
// }
// ]
例
好奇地看到一切吗?这是一个正在运行的应用程序!
这是一个 HTML 文件,没有任何构建或工具。您可以使用 nano 对其进行编辑。
<!DOCTYPE html>
<html lang="en">
<title>htm Demo</title>
<script type="module">
import { html, Component, render } from 'https://unpkg.com/htm/preact/standalone.module.js';
class App extends Component {
addTodo() {
const { todos = [] } = this.state;
this.setState({ todos: todos.concat(`Item ${todos.length}`) });
}
render({ page }, { todos = [] }) {
return html`
<div class="app">
<${Header} name="ToDo's (${page})" />
<ul>
${todos.map(todo => html`
<li>${todo}</li>
`)}
</ul>
<button onClick=${() => this.addTodo()}>Add Todo</button>
<${Footer}>footer content here<//>
</div>
`;
}
}
const Header = ({ name }) => html`<h1>${name} List</h1>`
const Footer = props => html`<footer ...${props} />`
render(html`<${App} page="All" />`, document.body);
</script>
</html>
Other Uses
Since htm is designed to meet the same need as JSX, you can use it anywhere you’d use JSX.
Generate HTML using vhtml:
import htm from 'htm';
import vhtml from 'vhtml';
const html = htm.bind(vhtml);
console.log( html`<h1 id=hello>Hello world!</h1>` );
// '<h1 id="hello">Hello world!</h1>'
Webpack configuration via jsxobj: (details here) (never do this)
import htm from 'htm';
import jsxobj from 'jsxobj';
const html = htm.bind(jsxobj);
console.log(html`
<webpack watch mode=production>
<entry path="src/index.js" />
</webpack>
`);
// {
// watch: true,
// mode: 'production',
// entry: {
// path: 'src/index.js'
// }
// }