导出和重构输入

FormKit输入包含大量的标记。这对于确保输入以可访问的方式编写非常有用。然而,有时候修改FormKit输入的现有结构是有意义的。使用FormKit CLI,我们可以导出FormKit的开源输入并修改它们的原始结构,甚至修改它们的功能。

在本指南中,我们将导出文本输入,并对其进行重构,以更好地支持浮动标签设计。

通过CLI导出

FormKit带有自己的CLI,使导出输入变得轻而易举。在项目的基本目录中运行以下命令:

npx formkit export

运行此命令会提示您选择要导出的FormKit开源输入之一:

? What input do you want to export? ›
❯   button
    submit
    checkbox
    file
    form
    group
    hidden
    list
    radio
  ↓ select

我们将选择文本输入,并允许CLI在/src目录下创建一个新的/inputs目录:

✔ What input do you want to export? › text
✔ What language should be used? › JavaScript
? Where should the input be exported to (relative to the current directory)? ›
./src/inputs

查看我们导出的输入text.js,我们可以看到组成FormKit输入的底层部分。这些部分作为小型可组合函数提供。每个部分代表一个单独的FormKitSchemaNode,传递给该部分的参数是其子节点:

// text.js
import {
  outer,
  inner,
  wrapper,
  label,
  help,
  messages,
  message,
  icon,
  prefix,
  suffix,
  textInput,
} from '@formkit/inputs'
/**
 * Input definition for a text.
 * @public
 */
export const text = {
  /**
   * The actual schema of the input, or a function that returns the schema.
   */
  schema: outer(
    wrapper(
      label('$label'),
      inner(
        icon('prefix', 'label'),
        prefix(),
        textInput(),
        suffix(),
        icon('suffix')
      )
    ),
    help('$help'),
    messages(message('$message.value'))
  ),
  /**
   * The type of node, can be a list, group, or input.
   */
  type: 'input',
  /**
   * An array of extra props to accept for this input.
   */
  props: [],
  /**
   * Additional features that should be added to your input
   */
  features: [],
}

在这个例子中,我们不打算覆盖默认的FormKit文本输入,而是创建一个自定义的文本输入,该输入将使用浮动标签。让我们将刚刚导出的文本文件重命名为floatingLabelTextInput.js

src/
  |inputs/
  |   |- t̶e̶x̶t̶ floatingLabelTextInput.js

floatingLabelTextInput.js中,让我们将导出的变量的名称从text更改为floatingLabelTextInput

...
export const t̶e̶x̶t̶ floatingLabelTextInput = {
  ...
}

注册输入

为了全局注册我们的“新”输入,我们需要将floatingLabelTextInput添加到全局配置中。我们可以在注册FormKit插件的任何地方执行此操作:

//main.js
import { createApp } from 'vue'
import App from './App.vue'
import { plugin, defaultConfig } from '@formkit/vue'
import '@formkit/themes/genesis'
import { floatingLabelTextInput } from '../src/inputs/floatingLabelTextInput'

const config = defaultConfig({
  inputs: {
    floatingLabelTextInput,
  },
})

createApp(App).use(plugin, config).mount('#app')

修改模式

现在,我们将修改floatingLabelTextInput的模式,以更好地支持浮动标签,通常使用CSS兄弟选择器~来实现。为了使用像:focus ~ label这样的CSS选择器,我们的<label>标签需要放在<input>标签之后。由于我们已经导出了模式,所以这个更改很容易实现:

export const floatingLabelTextInput = {
  schema: outer(
    wrapper(
      /*
      * 删除label
      */
      l̶a̶b̶e̶l̶(̶'̶$̶l̶a̶b̶e̶l̶'̶)̶, // ❌ 从这里删除
      inner(
        icon('prefix', 'label'),
        prefix(),
        textInput(),
        label('$label'), // 👈 现在放在这里
        suffix(),
        icon('suffix')
      )
    ),
    help('$help'),
    messages(message('$message.value'))
  ),
  ...
}

使用助手函数

@formkit/inputs包导出了许多助手函数,可以轻松应用于可组合模式函数。可用的助手函数有:

import { $attrs, $if, $for, $extend, $root } from '@formkit/inputs'

从FormKit的输入包中导入$attrs函数可以让我们使用附加属性扩展任何部分的模式。在这个例子中,我们使用它来修改标签部分,并将其类从formkit-label修改为formkit-label-floating。此外,我们还将添加一个data-has-value属性:

import {
  outer,
  inner,
  wrapper,
  label,
  help,
  messages,
  message,
  icon,
  prefix,
  suffix,
  textInput,
  /*
   * 导入$attrs
   */
  $attrs,
} from '@formkit/inputs'

export const floatingLabelTextInput = {
  schema: outer(
    wrapper(
      inner(
        icon('prefix', 'label'),
        prefix(),
        textInput(),
        /*
        * 使用$attrs函数将attrs对象传递给标签部分,其中包含新的类定义。
        */
        $attrs(
          {
            class: '$classes.labelFloating',
            'data-has-value': '$_value !== "" && $_value !== undefined',
            for: '$id',
          },
          label('$label')
        ),
        suffix(),
        icon('suffix')
      )
    ),
    help('$help'),
    messages(message('$message.value'))
  ),

  type: 'input',

  props: [],

  features: [],
}

在添加适当的样式之后,我们可以看到我们的新自定义输入将<label>移动到了HTML结构内部,并使用浮动标签:

加载实时示例

下一步

在本指南中,我们使用FormKit的CLI工具导出了内置的text输入,并将导出的文件作为新的浮动标签变体的起点。然而,导出功能使开发人员能够做更多的事情!无论是替换FormKit的现有输入,还是添加具有修改、添加、删除或移动部分的新自定义输入 - 我们期待看到您使用此功能的各种方式!

了解更多关于创建自定义输入的信息。阅读指南