模板化

Markup 使用名为 html标记模板文字 来描述要渲染的 HTML。

javascript
const temp = html`<h1>Hello World</h1>`

html 返回一个 HTMLTemplate 实例,其中包含可用于访问或执行许多操作的方法和属性。

渲染

定义模板后,有几种渲染模板的方法:

render

render 方法将采用 ShadowRootHTMLElementDocumentFragment 来附加内容。

javascript
temp.render(document.body)

模板的解析发生在渲染时,并且只会发生一次。对于其他渲染方法也是如此。

重复调用同一目标的 render 方法只能工作一次。您可以使用不同的目标调用它,以将内容移动到不同的位置。

javascript
temp.render(document.body) // will parse and append to document.body
temp.render(document.body) // will be ignored
temp.render(document.body) // will be ignored
temp.render(document.getElementById('app')) // will move content to #app

replace

replace 方法采用任何 HTMLTemplateNode,只要它不是 ShadowRootHTMLBodyElementHTMLHeadElementHTMLHtmlElement 即可在 DOM 中进行替换。

javascript
temp.replace(document.getElementById('app'))

render 方法类似,它只会解析一次内容。

javascript
const loading = html`<p>loading...</p>`

html`${loading}`.render(document.body)

doSomethingAsync().then(() => {
    const done = html`<p>Done</p>`

    done.replace(loading)
})

replace 方法非常强大,尤其是在使用异步渲染时,您可以临时渲染某些内容(例如加载指示器),然后在获得数据后替换它。这正是 suspense 实用程序的作用。

insertAfter

insertAfter 方法的工作原理与 render 方法完全相同。唯一的区别是它在提供的目标节点之后添加了模板内容。

javascript
temp.insertAfter(document.getElementById('app'))

另一个区别是它还可以将 HTMLTemplate 实例作为目标,从而允许依次渲染模板。

typescript
const items = [
    html`<li>Buy groceries</li>`,
    html`<li>Go to gym</li>`,
    html`<li>Write a blog</li>`,
]

html`<ul>
    ${items}
</ul>`.render(document.body)

html`<li>Read a book</li>`.insertAfter(items[1])

parentNode

parentNode 属性将告诉您模板的渲染位置。它将返回添加模板节点的元素。

mounted

渲染模板后,您可以使用 mounted 属性来检查您的模板是否已根据需要添加到目标。

mounted 属性不会告诉您模板是否实际附加到文档。为此,您可以使用 parentNode?.isConnected

javascript
const temp1 = html`one`.render(document.createDocumentFragment())
const temp2 = html`two`.render(document.body)

console.log(
    temp1.mounted, // true
    temp1.parentNode?.isConnected // false
)

console.log(
    temp2.mounted, // true
    temp2.parentNode?.isConnected // true
)

childNodes

childNodes 将为您提供由模板呈现的顶级节点数组。

javascript
const temp = html`
    Loose text
    <p>a paragraph</p>
    <button>click me</button>
    ending
`.render(document.body)

console.log(temp.childNodes) // [text, p, text, button, text]

unmount

要从目标中删除模板,您可以使用 unmount 方法。

javascript
temp.unmount()

unmount 应该是从 DOM 中删除模板的唯一方法。这是因为它还会递归地取消订阅任何状态。这意味着即使您嵌套模板,也会为所有模板调用 unmount

直接操作 DOM 可能会产生不良结果。

toString

您可以方便地获取模板当前渲染状态的字符串表示形式。

javascript
const temp = html`
    Loose text
    <p>a paragraph</p>
    <button>click me</button>
    ending
`.render(document.body)

console.log(temp.toString())
/* 
Loose text
<p>a paragraph</p>
<button> click me</button>
ending
 */

生命周期

还有其他方法可用于生命周期目的。您可以通过查看 lifecycle 文档了解更多信息。

编辑本文档