公用事业
Markup 提供了许多实用函数,可帮助您进行模板化或一般使用 DOM:
- element:允许您轻松创建DOM元素;
- suspense:允许您延迟渲染内容;
- repeat:允许您处理列表或重复内容;
- when:允许您有条件地渲染内容;
- visible:允许您推迟渲染直到元素进入视口;
- is and isNot:允许您快速检查状态的真实性
- and, or, & oneOf:允许您快速检查状态的条件
- pick:允许您深入读取状态对象键值
为什么需要公用事业?
在 Markup 中,函数是一等公民,这意味着反应数据由函数表示。为了简单起见,您可以创建处理模板之外的特定逻辑的函数,这样事情看起来很干净,并且逻辑是可重用的。
您可以创建实用函数来处理以下事情:
- 验证;
- 数据转换;
- 逻辑基础渲染;
- 缓存;
- 等等;
您只需要在处理状态时定义实用程序。其他一切都可以保留为静态数据。
实用程序只是在模板中呈现的函数,只要它们所依赖的状态发生变化就需要调用它们。
自定义实用程序
当您开始定义自己的实用程序时,使用状态和模板的力量就会显现出来。让我们看一个简单的例子:
我们有一个常见的场景,我们有一个使用状态的输入字段,并且我们需要显示特定的消息,无论该值是否有效。
javascript
const [value, updateValue] = state(null)
const handleChange = (event) => {
updateValue(event.target.value)
}
html` <input value="${value}" oninput="${handleChange}" /> `.render(
document.body
)我们可以直接在模板中添加消息的逻辑:
javascript
html`
<input value="${value}" onchange="${handleChange}" />
${() => {
if (/[a-z]{3,}/i.test(value())) {
return ''
}
return 'Value must me at least 3 characters'
}}
`.render(document.body)这还不错,但模板中的逻辑占用空间,而且很多逻辑使模板难以阅读。
我意识到,当输入无效时,我想将字段标记为红色,并且这依赖于我们在函数中具有的相同逻辑。因此,我可以将该逻辑提取到一个函数中以实现可重用性:
javascript
const [value, updateValue] = state(null)
const isPristine = () => value() === null
const isValidValue = () => /[a-z]{3,}/i.test(value())
const handleChange = (event) => {
updateValue(event.target.value)
}
html`
<input value="${value}" oninput="${handleChange}" />
${isPristine} ${isValidValue}
`.render(document.body)
// renders: <input> true false现在我有两个实用程序可以告诉我该值是否已更改,或者我可以在任何地方使用它来渲染任何内容是否有效。
但我不需要停在那里,我可以使用函数来表示我想要的任何东西,最终得到这样的结果:
javascript
const [value, updateValue] = state(null)
const isPristine = () => value() === null
const isValidValue = () => /[a-z]{3,}/i.test(value())
const valueCSSColor = () => (or(isPristine, isValidValue)() ? 'inherit' : 'red')
const handleChange = (event) => {
updateValue(event.target.value)
}
html`
<input
value="${value}"
oninput="${handleChange}"
style="color: ${valueCSSColor}"
/>
${when(
or(isPristine, isValidValue),
html`<p>Your name</p>`,
html`<p style="color: ${valueCSSColor}">
Name must be at least 3 characters
</p>`
)}
`.render(document.body)您可以看到我们有处理不同逻辑的函数,将它们组合成依赖于状态的更复杂的逻辑。
这种只需创建和组合函数来处理所有事情的能力进一步使 Markup 中的模板变得简单而有趣。
我们可以进一步将所有内容包装在可重用实用程序中,以处理可与多个表单字段一起使用的任何类型的表单输入值。
javascript
const formFieldValue = (pattern) => {
const [value, updateValue] = state(null)
const isPristine = () => value() === null
const isValid = () => pattern.test(value())
const isPristineOrValid = or(isPristine, isValid)
const color = () => (isPristineOrValid() ? 'inherit' : 'red')
return {
value,
updateValue,
color,
isPristine,
isValid,
isPristineOrValid,
}
}这使我可以轻松地为任何字段创建字段处理程序,如下所示:
javascript
const name = formFieldValue(/[a-z]{3,}/i)
const email = formFieldValue(/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i)
const handleNameChange = (event) => {
name.updateValue(event.target.value)
}
const handleEmailChange = (event) => {
email.updateValue(event.target.value)
}
html`
<input
type="text"
value="${name.value}"
oninput="${handleNameChange}"
style="color: ${name.color}"
/>
${when(
name.isPristineOrValid,
html`<p>Your name</p>`,
html`<p style="color: ${name.color}">
Name must be at least 3 characters
</p>`
)}
<input
type="email"
value="${email.value}"
oninput="${handleEmailChange}"
style="color: ${email.color}"
/>
${when(
email.isPristineOrValid,
html`<p>Your email</p>`,
html`<p style="color: ${email.color}">Email is not valid</p>`
)}
`.render(document.body)正如您所看到的,当谈到反应性时,Markup 严重且完全依赖于函数来完成工作。这种面向功能的性质使模板变得简单并且对任何人来说都熟悉。尝试一下!
编辑本文档