功能组件

Markup 不附带专用组件 API。组件只是返回 HTMLTemplate 实例的函数。

javascript
const MyButton = () => {
    return html` <button type="button">click me</button> `
}

这些函数的用途或外观完全取决于您。从上面的示例中,您可以使用 render 方法简单地渲染组件。

javascript
MyButton().render(document.body)

输入(props)

由于它的功能,您可以获取参数并通过适当的默认处理将它们直接注入到模板中。

javascript
const Button = ({ content = '', disabled = false, type = 'button' }) => {
    return html` <button type="${type}" disabled="${disabled}">
        ${content}
    </button>`
}

模板可以采用原始值或返回某个值的函数,该值可以是 state 或只是 dynamic value,在这种情况下,您可以让输入类型定义使用 StateGetter 类型。

typescript
enum MyButtonType {
    Button = 'button',
    Reset = 'reset',
    Submit = 'submit',
}

interface MyButtonProps {
    content: unknown
    disabled: boolean | StateGetter<boolean>
    type: MyButtonType | StateGetter<MyButtonType>
}

StateGetter 允许您传达组件将函数值作为输入的信息,这使得处理状态变得更加容易。

生命周期

您可以利用 effecthtml lifecycles 对组件安装、卸载和更新等操作做出反应,以完成您需要的一切。

javascript
const ChatMessages = () => {
    const [messages, updateMessages] = state([])

    onUpdate(() => {
        // todo: scroll to the bottom to show latest msg
    })

    const onMount = () => {
        const controller = new AbortController();
        const signal = controller.signal;

        fetch('...', { signal })
            .then((res) => {
                if(!res.ok) throw new Error(res.statusText)

                return res.json()
            })
            .then((res) => updateMessages(res.messages))
            .catch(console.error);

        // return a function to be called on unmount
        // where you can perform any clean ups
        return () => {
            controller.abort();
        }
    }

    return html`
        <ul>
            ${repeat(messages, msg => html`<li>${msg}</li>
        </ul>
    `)}
        .onMount(onMount)
        .onUpdate(onUpdate)
}

Markup 模板具有强大的生命周期,并且由于函数被调用一次并具有反应能力,因此您可以将所有内容封装在函数内,将所有内容留给 Markup 来管理。

编辑本文档