FormKit的模式是一种可序列化为JSON的数据格式,用于存储DOM结构和组件实现,包括FormKit表单。尽管专门用于实现和生成表单,但该格式能够生成任何HTML标记或使用任何第三方组件。
使用FormKit的<FormKitSchema>
组件来渲染模式,该组件默认情况下不会全局注册。您需要导入它:
import { FormKitSchema } from '@formkit/vue'
FormKit提供了对使用模式生成表单的一流支持。这使得可以将生成的表单存储在数据库、文件甚至二维码中!要生成一个表单,将您的模式数组传递给<FormKitSchema>
组件的:schema
属性。
<FormKitSchema :schema="yourSchemaArray" />
让我们来看一个快速示例:
我们在上面看到了许多功能,包括$el
和$cmp
属性,$formkit
属性的简写形式,验证,条件渲染,标签,帮助文本和多种类型的输入。我们将在本页面的其余部分详细介绍这些功能。
模式是一个对象或字符串(称为“模式节点”)的数组,其中每个数组项定义一个单独的模式节点。有3种类型的模式节点:
模式支持高级功能,如条件逻辑,布尔运算符,循环,插槽和数据作用域 - 所有这些功能都保证序列化为字符串。
使用$el
属性定义HTML元素。您可以使用$el
来渲染任何HTML元素。可以使用attrs
属性添加属性,使用children
属性分配内容:
请注意在上面的示例中,style
属性是独特的,它应该被定义为一个样式到值对的对象,而不是一个字符串。
组件可以使用$cmp
属性定义。$cmp
属性应该是一个字符串,引用全局定义的组件或通过library
属性传递给FormKitSchema
的组件:
为了通过library
属性传递具体的组件,最好使用Vue的markRaw
签名包装您的库。
除了模式数组(和可选的库),FormKitSchema
对象还可以包括一个data
属性。然后可以直接在模式中引用数据对象中的值 - 并且模式将保持原始数据对象的响应性。
要引用数据对象中的值,只需使用美元符号$
后跟数据对象的属性名。引用可以在attrs
、props
、条件和children
中使用:
请注意在上面的示例中,我们使用了一个数组来连接“Hello”和“$location”。我们这样做是因为模式中的数据引用和逻辑表达式必须始终以美元符号$
开头 - 否则它们将被视为未解析的字符串字面量。
模式支持调用您原始引用数据中的函数 - 甚至可以将数据引用作为该函数的参数!
就像JavaScript一样 - 您可以使用点语法object.property
访问深层嵌套对象的属性:
模式引用可以具有任何结构或属性,但在数据引用对象的根部有两个保留字:$slots
和$get
。
模式还支持布尔逻辑、比较和算术表达式。这些表达式可以在任何可以使用数据引用的地方使用(attrs
、props
、条件语句和children
):
表达式必须始终以$
开头。如果表达式的第一个元素是数据引用(例如:$count + 2
),那么它已经以$
开头,不需要进一步标记。然而,通常表达式的第一个字符不是美元符号 - 这些表达式需要用$:
进行"标记" - 例如$: ($count * 3) - 7
。
虽然它看起来非常像JavaScript - 模式表达式不是JavaScript。它们更适合被视为模板语言。表达式在setup
中被编译为功能性JavaScript,但语法与JavaScript不完全兼容。这提高了性能,并提供了一个关键的安全层,因为只有明确公开的数据和功能才能被执行。
模式表达式仅限于以下运算符和括号:
运算符 | 用例 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取模 |
&& | 布尔与 |
|| | 布尔或 |
=== | 严格相等 |
!== | 严格不相等 |
== | 宽松相等 |
!= | 宽松不相等 |
>= | 大于等于 |
<= | 小于等于 |
> | 大于 |
< | 小于 |
FormKit模式可以利用引用和表达式使模式节点和属性具有条件性。这些条件可以通过两种方式添加:
$el
和$cmp
节点上的if
属性。if/then/else
对象if
属性$el
和$cmp
模式节点都可以利用if
属性,它大致相当于Vue中的v-if
。如果分配给if
属性的表达式为真,节点将被渲染,否则将不会被渲染:
if/then/else
对象if/then/else
对象允许更复杂的条件逻辑。它可以用于有条件地渲染节点、模式节点列表、attrs
对象的值或props
对象的值。还可以嵌套if/then/else
对象以创建更复杂的结构 - 类似于JavaScript中的else if
语句。
if/then/else
您可以在通常使用模式节点的任何地方使用if/then/else
对象。这包括根模式数组或另一个模式节点的children
属性:
if/then/else
您还可以使用if/then/else
语句有条件地输出attrs
或props
的值:
$el
和$cmp
模式节点都支持循环。循环语法类似于Vue中的v-for
,并期望迭代一个对象或数组,并将当前迭代值分配给一个属性。可选地,您还可以捕获当前迭代的索引或属性:
有时模式表达式需要将字符串转换为数字。例如,在迭代过程中,键始终是字符串值,因此在上面的示例中,需要将$key
转换为整数后再加上1
。要执行此转换,我们只需将其乘以1:$key * 1
,然后再执行加法。
模式可以在模式中的任何位置呈现<FormKitSchema>
组件的插槽内容,就像呈现普通模式节点一样。所有作用域插槽都会自动提供给模式,存储在$slots
引用对象下:
有时需要将变量或未知属性或props的对象传递给$cmp
或$el
。在Vue中,我们可以使用v-bind
来实现这一点 - 在模式中,我们使用bind
属性:
有时候需要阻止解析给定的属性或prop。可以通过在属性或prop前加上__raw__
来实现:
{
$cmp: 'PriceComponent',
props: {
__raw__price: '$2.99'
}
}
在上面的示例中,__raw__
前缀将被移除,并且未解析的值$2.99
将作为price
prop传递给PriceComponent
。
另一个使用场景是渲染FormKit组件。<FormKit>
组件有一个sections-schema
prop,允许用户传递部分schema与其输入的各个部分合并。在这种特殊情况下,我们希望将schema块作为原始的JavaScript对象传递给<FormKit>
组件。为了实现这一点,我们再次使用__raw__
前缀来修饰sectionsSchema
prop:
请注意,如果从上面的示例中删除__raw__
前缀,前缀将不再起作用 — 这是因为在创建组件时,sectionsSchema
prop的值已经被解析而不是作为JavaScript对象传递。
虽然schema可以用于几乎任何目的,但主要目标是让开发人员使用可序列化的数据格式构建复杂和动态的表单。使用schema与FormKit输入很好地满足了这个用例。
假设你已经全局注册了FormKit
组件 —— 你可以通过使用$cmp
类型的schema节点从schema中渲染FormKit
输入:
虽然cmp
语法是通用的,适用于任何Vue组件,但对于FormKit输入来说有点冗长。为了简化操作,FormKit支持第四种节点类型$formkit
,它是完整的$cmp
格式的语法糖。
使用$formkit
简写时,props
对象会与顶级属性($formkit
的兄弟节点)进行扁平化处理。例如:
schema格式有一个专门针对FormKit输入的内置函数:$get
函数。该内置函数允许schema访问任何其他FormKit输入的上下文对象(即使在当前表单之外) —— 前提是所讨论的输入具有明确声明的id
prop。这使得schema能够有条件地响应你自己输入的状态:
要渲染一个表单元素,可以使用$formkit: 'form'
schema节点,或者将<FormKitSchema>
组件包装在<FormKit type="form">
组件中: