在本指南中,我们将逐步介绍创建、注册和使用自定义输入框的过程。具体来说,我们将创建一个“一次性密码”输入框(简称 OTP)。OTP 通常用于双因素身份验证,用户需要输入通过短信或身份验证应用程序发送的代码。让我们开始吧!
本指南假设您正在使用标准的 Vue 3 构建工具,如 Vite、Nuxt 3 或 Vue CLI,这些工具允许您导入 .vue
单文件组件。
首先,让我们创建输入框的组件文件。我们将其命名为 OneTimePassword.vue
:
<script setup>
const props = defineProps({
context: Object,
})
</script>
<template>
<div>更多内容即将到来...</div>
</template>
FormKit 提供了许多开箱即用的输入框功能,我们希望保留这些功能,例如标签、帮助文本和显示错误消息。我们只需要修改输入框的输入部分。我们可以使用 @formkit/vue
包中的 createInput
实用函数来保留这些标准的 FormKit 功能。
在构建输入框时,我们希望能够可视化其进度,因此让我们创建一个示例表单:
OneTimePassword.vue
createInput()
<FormKit>
组件的 type
属性。我们将这个示例表单命名为 Register.vue
:
太棒了!现在我们可以迭代我们的 OneTimePassword.vue
文件并查看结果。首先要注意的一件事是,我们的输入框已经支持标签、帮助文本、验证和其他通用的 FormKit 属性。这些功能都来自于 createInput()
。
此外,注意上面示例中的 <pre>
标签吗?它输出了表单数据的当前状态。我们将使用它来可视化自定义输入框的值。由于我们的输入框当前没有值,它不会出现在表单数据中。是时候改变这一点了!
让我们再次打开 OneTimePassword.vue
,将我们的 <div>
改为 <input>
标签。我们将从一个单独的文本输入框开始,然后逐步增加功能。但是,我们如何设置和显示自定义输入框的值呢?
所有自定义输入框都会传递一个强大的 上下文对象 作为 context
属性。为了让我们的输入框能够 设置 其值,它需要调用 context.node.input(value)
。为了正确地 显示 我们输入框的值,我们应该将输入框的 :value
属性设置为 context._value
。
我们的小输入框已经长大了!它可能看起来不太好看,但它现在可以读取和写入值了。作为证明,尝试将表单的 values
对象的初始值设置为 { two_factor_code: '12345' }
,您将看到输入框自动填充了该值。
好的,现在我们了解了如何创建输入框、如何使用它以及如何读取和写入值,让我们来解决实际的一次性密码输入框的“业务逻辑”。以下是我们的要求:
<input>
标签。对于我们的第一个要求,我们需要 n
个 <input>
标签。也许将数字的数量作为一个属性暴露出来会更好。为此,我们需要告诉我们的 createInput
函数,我们想要接受一个新的属性:
createInput(OneTimePassword, {
props: ['digits'],
})
现在我们可以访问 context.digits
。回到 OneTimePassword.vue
,让我们使用它来输出正确数量的 <input>
标签。
好了 - 我们有了多个输入框!我们的第一个要求已经完成:
<input>
标签。我们在上面的示例中添加了一些 CSS,但是在这个指南中我们不会深入讨论样式。建议使用 context.classes.yourKey
作为输入框中元素的类名。
请注意,在上面的示例中,当您在一个输入框中输入时,所有其他输入框都会同步为相同的值。这很好,但不是我们想要的。这是因为我们仍在使用相同的输入处理程序和 :value
。下面是改进输入的计划:
focus()
在下一个输入框上。digits
相同时,我们通过调用 context.node.input()
来更新输入框的值。太棒了!这开始按照我们的预期工作。让我们再次检查我们的要求:
<input>
标签。看起来我们只剩下一件事要做 - 复制和粘贴支持。幸运的是,浏览器有一个 paste
事件。为了确保我们的用户体验是一流的,我们将做出一个假设:如果用户正在复制/粘贴,他们正在尝试复制和粘贴整个代码。而不是代码的单个数字。这似乎是合理的。
我们只需要在任何输入框上捕获复制/粘贴事件,获取正在粘贴的文本,并将 tmp
值设置为该数字字符串。让我们再次编写另一个事件处理程序:
handlePaste(e) {
const paste = e.clipboardData.getData('text')
if (typeof paste === 'string') {
// 如果长度正确,则粘贴它。
this.tmp = paste.substr(0, this.max)
const inputs = e.target.parentElement.querySelectorAll('input')
// 聚焦在最后一个字符上
inputs.item(this.tmp.length - 1).focus()
}
}
我们的所有要求都已完成!
现在,我们已经开发出了一个出色的输入框,让我们在应用程序中注册它,这样我们就可以在任何地方使用它,只需使用字符串 otp
。打开您的 Vue 应用程序的主文件(其中包含 app.use(formKit)
)。我们只需添加以下内容:
import { createApp } from 'Vue'
import App from 'App.vue'
import OneTimePassword from './OneTimePassword.vue'
import { plugin, defaultConfig, createInput } from '@formkit/vue'
const app = createApp(App)
app.use(
plugin,
defaultConfig({
inputs: {
otp: createInput(OneTimePassword, {
props: ['digits'],
}),
},
})
)
app.mount('#app')
完成!现在您可以在应用程序的任何地方使用您的输入框:
<FormKit type="otp" digits="4" />
我们的一次性密码输入框工作得很好!以下是一些进一步完善的额外功能的想法:
希望本指南能帮助您了解如何声明、编写和注册自定义输入框。如果您想深入了解,请尝试阅读有关FormKit的核心内部和创建自定义输入框的内容!