我刚刚与 Dave 聊天,他告诉我 Haunted。它是 Hooks,但用于 原生 Web Components!非常酷。我认为这类工具的存在使得使用 Web Components 越来越容易接受——特别是在完全原生、无需构建步骤的方式中。
我知道 Web Components 存在各种问题,但通常让我远离它们的原因是 **缺乏良好的模板和重新渲染** 以及 **没有状态管理**。
但如今我们可以快速解决这两个问题……
首先,创建像 <my-app> 这样的组件 非常舒服
import { html } from "https://unpkg.com/lit-html/lit-html.js";
import { component } from "https://unpkg.com/haunted/haunted.js";
function App() {
return html`
<div class="module">
Hello, World!
</div>
`;
}
customElements.define("my-app", component(App));
然后我们可以使用 Hooks 添加一些状态
import { html } from "https://unpkg.com/lit-html/lit-html.js";
import { component, useState} from "https://unpkg.com/haunted/haunted.js";
function App() {
const [name, setName] = useState("Chris");
return html`
<div class="module">
Hello, ${name}!
</div>
`;
}
customElements.define("my-app", component(App));
本周的 CodePen 挑战 是使用星球大战 API,所以让我们发出一个 fetch 请求并使用它来填充状态。这是 useEffect 的一个很好的用例。
import { html } from "https://unpkg.com/lit-html/lit-html.js";
import { component, useState, useEffect } from "https://unpkg.com/haunted/haunted.js";
function App() {
const [planets, setPlanets] = useState([]);
useEffect(() => {
fetch('https://swapi.co/api/planets/?page=2')
.then(response => {
return response.json();
})
.then(data => {
let planets = data.results;
// remove ones with no diameters
planets = planets.filter(planet => planet.diameter !== "0");
setPlanets(planets);
});
}, []);
return html`
<style>
/* Shadow DOM styles */
</style>
<div class="all-planets">
${planets.map(planet => html`
<div class="planet" style="--dia: ${planet.diameter}px">
<span class="planet-name">
${planet.name}
</span>
</div>
`)}
</div>
`;
}
customElements.define("my-app", component(App));
这是一个合适的 Web Components!
查看 CodePen 上 Chris Coyier (@chriscoyier) 编写的
使用 Haunted.js 的星球大战 API。
在 CodePen 上。
我喜欢这样的想法。但是,我不知道如何调和这样一个事实,即添加一个库让我感觉我正在使用的 Web Components 不再是原生的了。你是怎么做到的?
你可以很容易地编写你自己的版本。例如:https://codesandbox.io/s/wc-simple-hooks-b3sh5
我正在使用 lit-html,但如果你愿意,你也可以删除它……
不想自己写所有东西。只是想知道如何在原生和非原生库的使用之间取得平衡。我只是在内心与它发生冲突。想知道其他人是如何调和这个问题的
我知道你的意思。现在你的投入只是在别的地方。但对我来说,它们仍然感觉相当原生
<my-thing>很高兴看到类似 React 的代码,但没有所有合成的东西,并且具有更好的互操作性。谢谢!
可惜既没有提到 HyperHTMLElement 也没有提到 lighterhtml,因为 Haunted 也适用于其他各种库。
还有一个关于 从其核心删除 lit-html 的讨论,这样 Stencil 等框架也可能从中受益。