导出和重构输入

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

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

通过CLI导出

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

npx formkit export

运行此命令会提示你选择任何FormKit的开源输入进行导出:

? 你想导出哪个输入? ›
❯   按钮
    提交
    复选框
    文件
    表单
    组
    隐藏
    列表
    单选
  ↓ 选择

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

✔ 你想导出哪个输入? › 文本
✔ 应使用哪种语言? › JavaScript
? 输入应导出到哪里(相对于当前目录)? ›
./src/inputs

看一下我们导出的输入,text.js,我们可以看到构成FormKit输入的底层部分。这些部分以小的可组合函数的形式提供。每个部分代表一个FormKitSchemaNode,传递给该部分的参数是其子项:

// text.js
import {
  outer,
  inner,
  wrapper,
  label,
  help,
  messages,
  message,
  icon,
  prefix,
  suffix,
  textInput,
} from '@formkit/inputs'
/**
 * 文本的输入定义。
 * @public
 */
export const text = {
  /**
   * 输入的实际模式,或返回模式的函数。
   */
  schema: outer(
    wrapper(
      label('$label'),
      inner(
        icon('prefix', 'label'),
        prefix(),
        textInput(),
        suffix(),
        icon('suffix')
      )
    ),
    help('$help'),
    messages(message('$message.value'))
  ),
  /**
   * 节点的类型,可以是列表、组或输入。
   */
  type: 'input',
  /**
   * 应接受此输入的额外属性的数组。
   */
  props: [],
  /**
   * 应添加到您的输入的附加功能
   */
  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(
      /*
      * Removing label
      */
      l̶a̶b̶e̶l̶(̶'̶$̶l̶a̶b̶e̶l̶'̶)̶, // ❌ removed from here
      inner(
        icon('prefix', 'label'),
        prefix(),
        textInput(),
        label('$label'), // 👈 and now placed here
        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,
  /*
   * Importing $attrs
   */
  $attrs,
} from '@formkit/inputs'

export const floatingLabelTextInput = {
  schema: outer(
    wrapper(
      inner(
        icon('prefix', 'label'),
        prefix(),
        textInput(),
        /*
        * Using $attrs function to pass attrs object to label section with new
          class definition.
        */
        $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: [],
}

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

加载实时示例

下一步

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

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