我有以下两个组件:
// component.js
// imports ...
function ListItem(item) {
const html = wire(item)
function render() {
return html`<li>${item.foo}</li>`
}
return render()
}
function List(items) {
const html = wire(items)
function render() {
return html`<ul>${items.map(ListItem)}</ul>`
}
return render()
}
我想将它们放在客户端和服务器之间共享的模块中。然而,据我所知,虽然 API 几乎相同,但在服务器上我必须从 viperHTML 模块导入函数,在客户端我必须使用 hyperHTML 模块。因此,我不能只在我的共享模块顶部导入函数,而是必须在调用站点传递给我的组件。
这样做我的同构组件将如下所示:
// component.js
function ListItem(html, item) {
//const html = wire(item) // <- NOTE
function render() {
return html`<li>${item.foo}</li>`
}
return render()
}
function List(html, itemHtmls /* :( tried to be consistent */, items) {
//const html = wire(items) // <- NOTE
function render() {
return html`<ul>${items.map(function(item, idx) {
return ListItem(itemHtmls[idx], item)
})}</ul>`
}
return render()
}
从服务器调用组件:
// server.js
const {hyper, wire, bind, Component} = require('viperhtml')
const items = [{foo: 'bar'}, {foo: 'baz'}, {foo: 'xyz'}]
// wire for the list
const listWire = wire(items)
// wires for the children
const listItemWires = items.map(wire)
const renderedMarkup = List(listWire, listItemWires, items)
从浏览器调用是完全一样的,期待 hyperhtml 的导入方式:
// client.js
import {hyper, wire, bind, Component} from 'hyperhtml/esm'
然而,编写这样的代码感觉很不愉快,因为我觉得 wire() 调用的结果应该存在于组件实例中。有没有更好的方法来编写同构的 hyperHTML/viperHTML 组件?