Dans ce guide, nous allons vous guider à travers le processus de création, d'enregistrement et d'utilisation d'une entrée personnalisée. Plus précisément, nous allons créer une entrée "mot de passe à usage unique" ("OTP" pour faire court). Les OTP sont couramment utilisés pour l'authentification à deux facteurs lorsqu'un utilisateur doit taper un code envoyé par SMS ou par une application d'authentification. Commençons !
Ce guide suppose que vous utilisez un outil de construction Vue 3 standard comme Vite, Nuxt 3, ou Vue CLI qui vous permettra d'importer des composants à fichier unique .vue
.
Pour commencer, créons le fichier de composant de notre entrée. Nous l'appellerons OneTimePassword.vue
:
<script setup>
const props = defineProps({
context: Object,
})
</script>
<template>
<div>Plus à venir ici...</div>
</template>
FormKit fournit beaucoup de fonctionnalités d'entrée prêtes à l'emploi que nous allons vouloir conserver - comme les étiquettes, le texte d'aide, et l'affichage des messages d'erreur. Tout ce que nous voulons vraiment modifier est la section d'entrée de notre entrée. Nous pouvons conserver ces fonctionnalités standard de FormKit en utilisant la fonction utilitaire createInput
du package @formkit/vue
.
Au fur et à mesure que nous construisons notre entrée, nous voudrons visualiser son progrès, alors créons un formulaire d'échantillon pour :
OneTimePassword.vue
createInput()
type
d'un composant <FormKit>
.Nous appellerons ce formulaire d'échantillon Register.vue
:
Excellent ! Maintenant, nous pouvons itérer sur notre fichier OneTimePassword.vue
et voir les résultats. L'une des premières choses à remarquer est comment notre entrée prend déjà en charge les étiquettes, le texte d'aide, la validation, et d'autres propriétés universelles de FormKit. Ces fonctionnalités sont fournies par createInput()
.
Aussi, avez-vous remarqué cette balise <pre>
dans l'exemple ci-dessus ? Elle affiche l'état actuel des données du formulaire. Nous l'utiliserons pour visualiser la valeur de notre entrée personnalisée. Comme notre entrée n'a actuellement aucune valeur, elle n'apparaît pas dans les données du formulaire. Il est temps de changer cela !
Ouvrons à nouveau OneTimePassword.vue
et changeons notre <div>
en une balise <input>
. Nous commencerons par une seule entrée de texte, et nous progresserons à partir de là. Mais comment définir et afficher réellement la valeur de notre entrée personnalisée ?
Toutes les entrées personnalisées reçoivent l'omnipotent objet contexte comme propriété context
. Pour que notre entrée puisse définir sa valeur, elle doit appeler context.node.input(value)
. Pour afficher correctement la valeur de notre entrée, nous devrions définir l'attribut :value
de l'entrée à context._value
.
Notre petite entrée a bien grandi ! Elle n'est peut-être pas jolie, mais elle lit et écrit maintenant des valeurs. Pour preuve, essayez de définir la valeur initiale de l'objet values
du formulaire à { two_factor_code: '12345' }
et vous verrez que l'entrée est automatiquement peuplée avec la valeur.
Ok, maintenant que nous comprenons comment créer une entrée, comment l'utiliser, et comment lire et écrire des valeurs — attaquons-nous à la véritable "logique métier" de notre entrée de mot de passe à usage unique. Voici nos exigences :
<input>
.Pour notre première exigence, nous avons besoin de n
balises <input>
. Il serait peut-être préférable d'exposer le nombre de chiffres en tant que prop. Pour ce faire, nous devons informer notre fonction createInput
que nous voulons accepter une nouvelle prop :
createInput(OneTimePassword, {
props: ['digits'],
})
Nous avons maintenant accès à context.digits
. Retour dans OneTimePassword.vue
, utilisons cela pour afficher le bon nombre de balises <input>
.
OK — nous avons plusieurs entrées ! Notre première exigence est complète :
<input>
.Nous avons ajouté une touche de CSS dans l'exemple ci-dessus, mais en général, nous n'allons pas nous plonger dans le style dans ce guide. Il est recommandé d'utiliser context.classes.yourKey
comme nom de classe des éléments de votre entrée.
Remarquez dans l'exemple ci-dessus que lorsque vous tapez dans une entrée, toutes les autres entrées sont synchronisées à la même valeur ? Plutôt sympa, mais ce n'est pas ce que nous voulons. C'est parce que nous utilisons toujours le même gestionnaire d'entrée et :value
. Voici un plan pour améliorer notre entrée :
focus()
sur l'entrée suivante.digits
, nous mettons à jour la valeur de l'entrée en appelant context.node.input()
.Super ! Cela commence à fonctionner comme nous l'attendons. Vérifions à nouveau nos exigences :
<input>
.Il semble que nous n'ayons plus qu'une chose à faire : le support de copier & coller. Heureusement, les navigateurs ont un événement paste
. Pour garantir une expérience utilisateur de premier ordre, nous ferons une supposition : si un utilisateur copie/colle, il essaie de copier et coller l'ensemble du code. Pas un seul chiffre du code. Cela semble raisonnable.
Tout ce que nous avons à faire est de capturer l'événement de copier/coller sur l'une de nos balises d'entrée, d'obtenir le texte collé, et de définir la valeur tmp
à cette chaîne de chiffres. Préparons un autre gestionnaire d'événements :
handlePaste(e) {
const paste = e.clipboardData.getData('text')
if (typeof paste === 'string') {
// Si c'est de la bonne longueur, collez-le.
this.tmp = paste.substr(0, this.max)
const inputs = e.target.parentElement.querySelectorAll('input')
// Concentrez-vous sur le dernier caractère
inputs.item(this.tmp.length - 1).focus()
}
}
Toutes nos exigences sont maintenant remplies !
Maintenant que nous avons élaboré une excellente entrée, enregistrons-la avec notre application afin de pouvoir l'utiliser n'importe où en utilisant simplement la chaîne otp
. Ouvrez le fichier principal de votre application Vue (où app.use(formKit)
est). Nous allons simplement l'ajouter :
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')
C'est fait ! Maintenant, vous pouvez utiliser votre entrée n'importe où dans votre application :
<FormKit type="otp" digits="4" />
Notre entrée de mot de passe à usage unique fonctionne très bien ! Voici quelques idées de fonctionnalités supplémentaires que nous pourrions développer encore plus :
Espérons que ce guide vous a aidé à comprendre comment les entrées personnalisées sont déclarées, écrites et enregistrées. Si vous voulez approfondir, essayez de lire sur les internes de base de FormKit et la création d'entrées personnalisées !