# 构建表单

构建表单是 Vue Formulate 的一流功能,可以通过以下两种方式完成:

上面的方法非常相似——都使用具有 prop 值的对象数组。 这非常有效,因为 Vue Formulate 是一个组件优先的库, 几乎所有的功能都可以通过 props 访问。 此外,插槽组件 等功能允许自定义渲染的表单域, 而无需自带组件(尽管您可以)。

# 模式

模式是在 2.4 版本中引入的,允许生成带有group字段、包装器和您自己的组件的复杂表单。 展示胜于讲述,因此这里有一个包含多个示例的交互式 JSON 游乐场。在此之后,我们将更详细地介绍模式的结构。

# 交互式 JSON 游乐场

# 模式表单域

模式只是对象的数组,其中每个对象都表示要给生成的组件或标记的 prop。默认情况下,架构中的对象假定为 FormulateInput 组件。 事实上,最简单的有效模式是一个只带有空对象的数组,该对象 [{}] 呈现为一个空文本字段。

这些模式数组可以作为 prop 直接传递给 <FormulateForm><FormulateSchema>。 由于 <FormulateForm> 添加了模型绑定,除非您有高级需求,否则它是最方便的选择。

<template>
  <FormulateForm
    v-model="values"
    :schema="schema"
  />
</template>

<script>
export default {
  data () {
    return {
      values: {},
      schema: [
        {
          type: 'password',
          name: 'password',
          label: 'Enter a new password',
          validation: 'required'
        },
        {
          type: 'password',
          name: 'password_confirm',
          label: 'Confirm your password',
          validation: '^required|confirm:password',
          validationName: 'Password confirmation'
        },
        {
          type: 'submit',
          label: 'Change password'
        }
      ]
    }
  }
}
</script>

# 模式组件

模式不限于 FormulateInput 元素。 每个对象都可以定义一个 component 属性来指定要呈现的任何组件或 HTML 标记。

[
  {
    component: 'img',
    src: '/logo.svg',
    style: 'width: 50px;'
  },
  {
    component: 'Badge',
    text: '2.4.0'
  },
]
2.4.0

# 模式子级

最后一部分,拼图也是嵌套模式的能力。例如,您可能想要包装两个元素,或使用一个 group 表单域。模式的深度或大小没有限制。

[
  {
    type: 'group',
    repeatable: true,
    name: 'addresses',
    addLabel: '+ Address',
    children: [
      {
        name: 'street',
        label: 'Street address'
      },
      {
        name: 'city',
        label: 'City',
      },
      {
        component: 'div',
        class: 'double-row',
        children: [
          {
            name: 'state',
            type: 'select',
            label: 'State',
            options: {
              va: 'Virginia',
              fl: 'Florida',
              ne: 'Nebraska',
              ca: 'California'
            },
          },
          {
            name: 'zip',
            label: 'Zip',
          },
        ]
      }
    ]
  }
]
Remove

# 模式事件 2.5

模式还支持事件绑定。可以通过三种方式将事件绑定到您的模式中:

  • 简单的事件监听器
  • 重命名的事件侦听器
  • 内联函数

# 简单的事件监听器

将事件绑定到架构元素就像 @{eventName} 在元素上包含属性一样简单。例如,给定这个架构:

[
  {
    "type": "text",
    "name": "username",
    "@blur": true
  }
]

我们现在可以通过 <FormulateForm><FormulateSchema> 向 username 元素添加事件侦听器来侦听 blur 事件:

<FormulateForm
  :schema="schema"
  @blur="handleBlur"
/>

# 重命名的事件侦听器

当您只需要侦听模式中的一两个事件时,简单事件侦听器非常有用,但是当您需要侦听多个模式节点上的多 个事件时会发生什么?例如,如果长表单中的每个输入都侦听 @focus 事件, 则确定哪个输入已被关注可能会令人沮丧。

为了解决这个问题,您可以通过简单地提供一个新的事件名称作为您的 @{eventName} 属性值来重命名发出的事件。 您可以选择任何字符串(kebab-case推荐)。例如:

[
  {
    "label": "Select a username",
    "type": "text",
    "name": "username",
    "@focus": "focus-username"
  },
  {
    "label": "Select a password",
    "type": "password",
    "name": "password",
    "@focus": "focus-password"
  },
  {
    "label": "Confirm your password",
    "validation": "confirm",
    "type": "password",
    "name": "password_confirm",
    "@focus": "focus-confirm"
  }
]
<FormulateForm
  :schema="schema"
  @focus-username="focusedOn = 'username'"
  @focus-password="focusedOn = 'password'"
  @focus-confirm="focusedOn = 'confirm'"
>
  Now we know the last focus was <strong>{{ focusedOn }}</strong>
</FormulateForm>
Now we know the last focus was Not yet focused

# 内联函数

也可以将事件侦听器函数直接绑定到您的架构中。 此选项(显然)不适用于简单的 JSON,但如果您将架构存储在组件中, 或者如果您从 JavaScript 文件导出架构,则它非常有用。

export default [
  {
    label: 'Where would you prefer to live?',
    type: 'select',
    name: 'location',
    options: ['Cleveland', 'Fiji', 'San Francisco',],
    '@change': (e) => e.target.value === 'Fiji' ? alert('🏝') : alert('🤔')
  }
]

# 简单迭代

因为 Vue Formulate 强调单一表单域 API,它使 DIY 表单生成变得简单。 在最简单的形式中,您只需要一个要表示表单域的对象数组即可。

<template>
  <FormulateForm>
    <FormulateInput
      v-for="item in items"
      :key="item.name"
      v-bind="item"
    />
  </FormulateForm>
</template>

<script>
export default {
  data () {
    return {
      items: [
        {
          name: 'email',
          label: 'Your email',
          validation: 'required|email'
        }
      ]
    }
  }
}
</script>

这个简单的功能实际上可以生成相当健壮的表单,因为您可以通过 props 完全控制您的表单域:

JSON 源码
[
  {
    type: 'text',
    name: 'name',
    label: 'What is your name?',
    placeholder: 'Your name...',
    validation: 'required'
  },
  {
    type: 'text',
    name: 'address',
    label: 'What is your street address?',
    placeholder: 'Your address...',
    help: 'Where would you like your product shipped?',
    validation: 'required'
  },
  {
    type: 'radio',
    name: 'method',
    label: 'What shipping method would you like?',
    options: [
      { value: 'fedex_overnight', id: 'fedex_overnight', label: 'FedEx overnight' },
      { value: 'fedex_ground', id: 'fedex_ground', label: 'FedEx ground' },
      { value: 'usps', id: 'usps', label: 'US Postal Service' }
    ],
    value: 'fedex_ground',
    'validation-name': 'Shipping method',
    validation: 'required'
  },
  {
    name: 'submit',
    type: 'submit',
    label: 'Submit order'
  }
]
Where would you like your product shipped?