Au cœur du framework FormKit se trouve @formkit/core
. Ce package sans dépendance est responsable de presque toutes les fonctions critiques de bas niveau de FormKit, telles que :
La fonctionnalité du noyau de FormKit n'est pas exposée à votre application via une instance centralisée, mais plutôt un ensemble distribué de "nœuds" (FormKitNode
), où chaque nœud représente une entrée unique.
Cela reflète le HTML — en fait, la structure du DOM est en réalité un arbre général et les nœuds du noyau de FormKit reflètent cette structure. Par exemple, un formulaire de connexion simple pourrait être représenté par le graphique d'arbre suivant :
Dans ce diagramme, un nœud form
est parent de trois nœuds enfants — email
, password
et submit
. Chaque composant d'entrée dans le graphique "possède" un nœud du noyau de FormKit, et chaque nœud contient ses propres options, configuration, props, événements, plugins, crochets de cycle de vie, etc. Cette architecture garantit que les fonctionnalités principales de FormKit sont découplées du framework de rendu (Vue) — une clé pour réduire les effets secondaires et maintenir des performances extrêmement rapides.
De plus, cette architecture décentralisée permet une flexibilité énorme. Par exemple — un formulaire peut utiliser des plugins différents des autres formulaires dans la même application, un groupe d'entrée peut modifier la configuration de ses sous-entrées, et les règles de validation peuvent même être écrites pour utiliser les props d'une autre entrée.
Chaque composant <FormKit>
possède un seul nœud central, et chaque nœud doit être de l'un des trois types :
Les nœuds centraux sont toujours de l'un des trois types (input, list ou group). Ce ne sont pas les mêmes que les types d'entrée — dont il peut y avoir une variation illimitée. Strictement parlant, toutes les entrées ont 2 types : leur type de nœud (comme input
), et leur type d'entrée (comme checkbox
).
La plupart des entrées natives de FormKit ont un type de nœud input
— elles opèrent sur une valeur unique. La valeur elle-même peut être de n'importe quel type, comme des objets, des tableaux, des chaînes de caractères et des nombres — toute valeur est acceptable. Cependant, les nœuds de type input
sont toujours des feuilles — ce qui signifie qu'ils ne peuvent pas avoir d'enfants.
import { createNode } from '@formkit/core'
const input = createNode({
type: 'input', // par défaut à 'input' si non spécifié
value: 'hello node world',
})
console.log(input.value)
// 'hello node world'
Une liste est un nœud qui produit une valeur de tableau. Les enfants d'un nœud de liste produisent une valeur dans le tableau de la liste. Les noms des enfants immédiats sont ignorés — à la place, chacun se voit attribuer un indice dans le tableau de la liste.
import { createNode } from '@formkit/core'
const list = createNode({
type: 'list',
children: [
createNode({ value: 'paprika@example.com' }),
createNode({ value: 'bill@example.com' }),
createNode({ value: 'jenny@example.com' }),
],
})
console.log(list.value)
// ['paprika@example.com', 'bill@example.com', 'jenny@example.com']
Un groupe est un nœud qui produit une valeur d'objet. Les enfants d'un nœud de groupe utilisent leur name
pour produire une propriété du même nom dans l'objet de valeur du groupe — <FormKit type="form">
est une instance de groupe.
import { createNode } from '@formkit/core'
const group = createNode({
type: 'group',
children: [
createNode({ name: 'meat', value: 'turkey' }),
createNode({ name: 'greens', value: 'salad' }),
createNode({ name: 'sweets', value: 'pie' }),
],
})
console.log(group.value)
// { meat: 'turkey', greens: 'salad', sweets: 'pie' }
En plus de spécifier le type
de nœud lors de l'appel à createNode()
, vous pouvez passer n'importe laquelle des options suivantes :
Options | Par défaut | Description |
---|---|---|
children | [] | Instances de FormKitNode enfants. |
config | {} | Options de configuration. Celles-ci deviennent les valeurs par défaut de l'objet props . |
name | {type}_{n} | Le nom du nœud/entrée. |
parent | null | L'instance de FormKitNode parent. |
plugins | [] | Un tableau de fonctions de plugin. |
props | {} | Un objet de paires clé/valeur qui représentent les détails de l'instance de nœud actuelle. |
type | input | Le type de FormKitNode à créer (list , group , ou input ). |
value | undefined | La valeur initiale de l'entrée. |
FormKit utilise un système de configuration basé sur l'héritage. Toutes les valeurs déclarées dans l'option config
sont automatiquement transmises aux enfants (et à tous les descendants) de ce nœud, mais pas aux frères et sœurs ou aux parents. Chaque nœud peut remplacer ses valeurs héritées en fournissant sa propre configuration, et ces valeurs seront à leur tour héritées par tous les enfants et descendants plus profonds. Par exemple :
const parent = createNode({
type: 'group',
config: {
color: 'yellow',
},
children: [
createNode({
type: 'list',
config: { color: 'pink' },
children: [createNode(), createNode()],
}),
createNode(),
],
})
Le code ci-dessus aboutira à ce que chaque nœud ait la configuration suivante :
Il est recommandé de lire les valeurs de configuration à partir de node.props
plutôt que de node.config
. La section suivante détaille cette fonctionnalité.
Les objets node.props
et node.config
sont étroitement liés. node.config
doit être considéré comme les valeurs initiales pour node.props
. props
est un objet de forme arbitraire qui contient des détails sur l'instance actuelle du nœud.
La meilleure pratique est de toujours lire les données de configuration et de propriétés à partir de node.props
même si la valeur d'origine est définie à l'aide de node.config
. Les props explicitement définis ont la priorité sur les options de configuration.
const child = createNode({
props: {
flavor: 'cherry',
},
})
const parent = createNode({
type: 'group',
config: {
size: 'large',
flavor: 'grape',
},
children: [child],
})
console.log(child.props.size)
// affiche : 'large'
console.log(child.props.flavor)
// affiche : 'cherry'
Lorsque vous utilisez le composant <FormKit>
, toutes les props définies pour le type d'entrée type
sont automatiquement définies comme propriétés de node.props
. Par exemple : <FormKit label="Email" />
résulterait en node.props.label
étant Email
.
Vous pouvez définir la valeur initiale d'un nœud en fournissant l'option value
sur createNode()
— mais FormKit est tout au sujet de l'interactivité, alors comment mettons-nous à jour la valeur d'un nœud déjà défini ? En utilisant node.input(value)
.
import { createNode } from '@formkit/core'
const username = createNode()
username.input('jordan-goat98')
console.log(username.value)
// undefined 👀 attendez — quoi !?
Dans l'exemple ci-dessus, username.value
est toujours indéfini immédiatement après avoir été défini parce que node.input()
est asynchrone. Si vous avez besoin de lire la valeur résultante après avoir appelé node.input()
, vous pouvez attendre la promesse retournée.
import { createNode } from '@formkit/core'
const username = createNode()
username.input('jordan-goat98').then(() => {
console.log(username.value)
// 'jordan-goat98'
})
Comme node.input()
est asynchrone, le reste de notre formulaire n'a pas besoin de recalculer ses dépendances à chaque frappe. Cela offre également l'opportunité d'effectuer des modifications sur la valeur non stabilisée avant qu'elle ne soit "engagée" dans le reste du formulaire. Cependant — pour une utilisation interne du nœud uniquement — une propriété _value
contenant la valeur non stabilisée de l'entrée est également disponible.
Vous ne pouvez pas directement assigner la valeur d'une entrée node.value = 'foo'
. Au lieu de cela, vous devriez toujours utiliser node.input(value)
Maintenant que nous comprenons que node.input()
est asynchrone, explorons comment FormKit résout le problème de l'arbre "stabilisé". Imaginez qu'un utilisateur tape rapidement son adresse e-mail et appuie sur "entrée" très rapidement — soumettant ainsi le formulaire. Puisque node.input()
est asynchrone, des données incomplètes seraient probablement soumises. Nous avons besoin d'un mécanisme pour savoir quand le formulaire entier est "stabilisé".
Pour résoudre cela, les nœuds de FormKit suivent automatiquement les "perturbations" de l'arbre, du sous-arbre et du nœud. Cela signifie que le formulaire (généralement le nœud racine) connaît toujours l'état de stabilisation de tous les champs qu'il contient.
Le graphique suivant illustre ce "comptage des perturbations". Cliquez sur n'importe quel nœud de saisie (bleu) pour simuler l'appel de node.input()
et remarquez comment le formulaire entier est toujours conscient du nombre de nœuds "perturbés" à tout moment. Lorsque le nœud racine a un compte de perturbations de 0
, le formulaire est stabilisé et sûr à soumettre.
import { createNode } from '@formkit/node'
const form = createNode({
type: 'group',
children: [
createNode(),
createNode(),
createNode()
],
})
// ...
// interaction utilisateur :
async function someEvent () {
await form.settled
// nous savons maintenant que le formulaire est complètement "stabilisé"
// et que form.value est précis.
}
L'entrée <FormKit type="form">
intègre déjà ce comportement d'attente. Elle n'appellera pas votre gestionnaire @submit
tant que votre formulaire n'est pas complètement stabilisé. Cependant, lors de la création de champs de saisie avancés, il peut être utile de comprendre ces principes sous-jacents.
Parfois, il peut être utile d'obtenir l'instance sous-jacente d'un nœud à partir du composant Vue <FormKit>
. Il existe trois méthodes principales pour récupérer le nœud d'un champ de saisie.
getNode()
(ou le $formkit.get()
du plugin Vue pour l'API Options)useFormKitNodeById
@node
.ref
de template.getNode()
Lorsque vous utilisez FormKit, vous pouvez accéder à un nœud en lui attribuant un id
puis en y accédant par cette propriété via la fonction getNode()
.
Vous devez attribuer un id
au champ de saisie pour utiliser cette méthode.
Lorsque vous utilisez l'API Options de Vue, vous pouvez accéder au même comportement getNode()
en utilisant this.$formkit.get()
.
useFormKitNodeById()
La fonction de composition useFormKitNodeById
vous permet d'accéder à un nœud par son id
depuis un composant Vue en retournant une ref
Vue qui sera peuplée avec l'instance FormKitNode
dès qu'elle aura été créée.
Pour d'autres fonctions de composition similaires, consultez la documentation sur les composables.
Vous devez attribuer un id
à l'entrée pour utiliser cette méthode.
Une autre façon d'obtenir le nœud
sous-jacent est d'écouter l'événement @node
qui est émis une seule fois lorsque le composant initialise le nœud pour la première fois.
Attribuer un composant <FormKit>
à une ref
permet également un accès facile au nœud.
Pour parcourir les nœuds au sein d'un groupe ou d'une liste, utilisez node.at(address)
— où address
est le nom
du nœud auquel on accède (ou le chemin relatif vers le nom). Par exemple :
import { createNode } from '@formkit/core'
const group = createNode({
type: 'group',
children: [createNode({ name: 'email' }), createNode({ name: 'password' })],
})
// Retourne le nœud email
group.at('email')
Si le nœud de départ a des frères et sœurs, il tentera de localiser une correspondance chez les frères et sœurs (en interne, c'est ce que FormKit utilise pour des règles de validation comme confirm:address
).
import { createNode } from '@formkit/core'
const email = createNode({ name: 'email' })
const password = createNode({ name: 'password' })
const group = createNode({
type: 'group',
children: [email, password],
})
// Accède au frère pour retourner le nœud password
email.at('password')
Vous pouvez aller plus loin qu'un niveau en utilisant un chemin relatif avec une syntaxe pointée. Voici un exemple plus complexe :
import { createNode } from '@formkit/core'
const group = createNode({
type: 'group',
children: [
createNode({ name: 'team' }),
createNode({
type: 'list',
name: 'users',
children: [
createNode({
type: 'group',
children: [
createNode({ name: 'email' }),
createNode({ name: 'password', value: 'foo' }),
],
}),
createNode({
type: 'group',
children: [
createNode({ name: 'email' }),
createNode({ name: 'password', value: 'fbar' }),
],
}),
],
}),
],
})
// affiche : 'foo'
console.log(group.at('users.0.password').value)
Remarquez comment le parcours de la list
utilise des clés numériques, c'est parce que le type list
utilise automatiquement les index de tableau.
Les adresses de nœuds peuvent également être exprimées sous forme de tableaux. Par exemple, node.at('foo.bar')
pourrait être exprimé comme node.at(['foo', 'bar'])
.
Également disponibles pour utilisation dans node.at()
sont quelques "jetons" spéciaux :
Jeton | Description |
---|---|
$parent | L'ancêtre immédiat du nœud courant. |
$root | Le nœud racine de l'arbre (le premier nœud sans parent). |
$self | Le nœud courant dans le parcours. |
find() | Une fonction qui effectue une recherche en largeur d'abord pour une valeur et propriété correspondantes. Par exemple : node.at('$root.find(555, value)') |
Ces jetons sont utilisés dans les adresses en syntaxe pointée tout comme vous utiliseriez le nom d'un nœud :
import { createNode } from '@formkit/core'
const secondEmail = createNode({ name: 'email' })
createNode({
type: 'group',
children: [
createNode({ name: 'team', value: 'charlie@factory.com' }),
createNode({
type: 'list',
name: 'users',
children: [
createNode({
type: 'group',
children: [
createNode({ name: 'email', value: 'james@peach.com' }),
createNode({ name: 'password', value: 'foo' }),
],
}),
createNode({
type: 'group',
children: [
secondEmail, // Nous allons commencer ici.
createNode({ name: 'password', value: 'fbar' }),
],
}),
],
}),
],
})
// Naviguer du second email au premier
console.log(secondEmail.at('$parent.$parent.0.email').value)
// affiche : charlie@factory.com
Les nœuds ont leurs propres événements qui sont émis pendant le cycle de vie du nœud (sans rapport avec les événements de Vue).
Pour observer un événement donné, utilisez node.on()
.
// Écouter toute propriété étant définie ou changée.
node.on('prop', ({ payload }) => {
console.log(`la propriété ${payload.prop} a été définie à ${payload.value}`)
})
node.props.foo = 'bar'
// affiche : la propriété foo a été définie à bar
Les fonctions de rappel des gestionnaires d'événements reçoivent toutes un seul argument de type FormKitEvent
, la structure de l'objet est :
{
// Le contenu de l'événement — une chaîne, un objet, etc.
payload: { cause: 'glace', duration: 200 },
// Le nom de l'événement, cela correspond au premier argument de node.on().
name: 'brain-freeze',
// Si cet événement doit remonter au parent suivant ou non.
bubble: true,
// Le FormKitNode original qui a émis l'événement.
origin: node,
}
Les événements des nœuds (par défaut) remontent dans l'arbre des nœuds, mais node.on()
ne répondra qu'aux événements émis par le même nœud. Cependant, si vous souhaitez également attraper les événements remontant des descendants, vous pouvez ajouter la chaîne .deep
à la fin du nom de votre événement :
import { createNode } from '@formkit/core'
const group = createNode({ type: 'group' })
group.on('created.deep', ({ payload: child }) => {
console.log('nœud enfant créé :', child.name)
})
const child = createNode({ parent: group, name: 'party-town-usa' })
// affiche : 'nœud enfant créé : party-town-usa'
Chaque appel pour enregistrer un observateur avec node.on()
retourne un « reçu » — une clé générée aléatoirement — qui peut être utilisée plus tard pour arrêter d'observer cet événement (similaire à setTimeout()
et clearTimeout()
) en utilisant node.off(reçu)
.
const reçu = node.on('input', ({ payload }) => {
console.log('reçu en entrée : ', payload)
})
node.input('foobar')
// affiche : 'reçu en entrée : foobar'
node.off(reçu)
node.input('fizz buzz')
// pas d'affichage
Voici une liste complète de tous les événements émis par @formkit/core
. Le code tiers peut émettre des événements supplémentaires non inclus ici.
Nom | Charge utile | Bulles | Description |
---|---|---|---|
commit | quelconque | oui | Émis quand la valeur d'un nœud est validée mais avant qu'elle ne soit transmise au reste du formulaire. |
config:{propriété} | quelconque (la valeur) | oui | Émis à chaque fois qu'une option de configuration spécifique est définie ou modifiée. |
count:{propriété} | quelconque (la valeur) | non | Émis à chaque fois qu'une valeur de compteur d'un grand livre change. |
child | FormKitNode | oui | Émis lorsqu'un nouveau nœud enfant est ajouté, créé ou assigné à un parent. |
created | FormKitNode | oui | Émis immédiatement avant que le nœud ne soit retourné lors de l'appel à createNode() (les plugins et fonctionnalités ont déjà été exécutés). |
defined | FormKitTypeDefinition | oui | Émis lorsque le "type" d'un nœud est défini, cela se produit généralement pendant createNode() . |
destroying | FormKitNode | oui | Émis lorsque node.destroy() est appelé, après qu'il a été détaché de tout parent. |
dom-input-event | Event | oui | Émis lorsque le gestionnaire DOMInput est appelé, utile pour obtenir l'événement d'entrée HTML original dans le cœur. |
input | quelconque (la valeur) | oui | Émis lorsque node.input() est appelé — après que le crochet input a été exécuté. |
message-added | FormKitMessage | oui | Émis lorsqu'un nouveau message a été ajouté à node.store . |
message-removed | FormKitMessage | oui | Émis lorsqu'un message de node.store a été supprimé. |
message-updated | FormKitMessage | oui | Émis lorsqu'un message de node.store a été modifié. |
mounted | aucun | oui | Émis lorsque le composant <FormKit> qui possède ce nœud est monté sur le DOM. |
prop:{nomProp} | quelconque (la valeur) | oui | Émis à chaque fois qu'une prop spécifique est définie ou modifiée. |
prop | { prop: string, value: any } | oui | Émis à chaque fois qu'une prop est définie ou modifiée. |
reset | FormKitNode | oui | Émis à chaque fois qu'un formulaire ou un groupe est réinitialisé. |
settled | booléen | non | Émis à chaque fois qu'un comptage de perturbation d'un nœud se stabilise ou se déstabilise. |
settled:{nomCompteur} | booléen | non | Émis à chaque fois qu'un compteur spécifique d'un grand livre se stabilise (retourne à zéro). |
unsettled:{nomCompteur} | booléen | non | Émis à chaque fois qu'un compteur spécifique d'un grand livre devient instable (dépasse zéro). |
text | chaîne ou FormKitTextFragment | non | Émis après que le crochet text a été exécuté — généralement lors du traitement de texte d'interface qui a pu être traduit. |
Lorsqu'une option de configuration change, tous les nœuds héritiers (y compris le nœud d'origine) émettront également des événements prop
et prop:{nomProp}
, tant qu'ils ne remplacent pas cette propriété dans leurs propres objets props
ou config
.
Les événements Node sont émis avec node.emit()
. Vous pouvez utiliser cette fonctionnalité pour émettre vos propres événements synthétiques depuis vos propres plugins.
node.emit('myEvent', payloadGoesHere)
Un troisième argument facultatif bubble
est également disponible. Lorsqu'il est défini sur false
, il empêche votre événement de remonter à travers l'arborescence du formulaire.
Les hooks sont des dispatchers de middleware qui sont déclenchés pendant les opérations du cycle de vie prédéfinies. Ces hooks permettent au code externe d'étendre la fonctionnalité interne de @formkit/core
. Le tableau suivant détaille tous les hooks disponibles :
Hook | Valeur | Description |
---|---|---|
classes |
| Dispatché après que toutes les opérations de classe ont été exécutées, avant la conversion finale en chaîne de caractères. |
commit | any | Dispatché lors de la définition de la valeur d'un nœud après l'input et le debounce de node.input() est appelé. |
commitRaw | any | Dispatché lors de la définition de la valeur d'un nœud après l'input et le debounce de node.input() est appelé. |
error | string | Dispatché lors du traitement d'une erreur lancée — les erreurs sont généralement des entrées, et la sortie finale devrait être une chaîne de caractères. |
init | FormKitNode | Dispatché après que le nœud est initialement créé mais avant qu'il soit retourné dans createNode() . |
input | any | Dispatché de manière synchrone à chaque événement d'entrée (à chaque frappe) avant commit . |
message | FormKitMessage | Dispatché lorsqu'un message est en train d'être défini sur node.store |
prop |
| Dispatché lorsqu'une prop est en train d'être assignée. |
setErrors | { localErrors: ErrorMessages, childErrors?: ErrorMessages } | Dispatché lorsque des erreurs explicites sont en train d'être définies sur un nœud (pas des erreurs de validation). |
submit | Record<string, any> | Dispatché lorsque le formulaire FormKit est soumis et passe la validation. Ce hook vous permet de modifier les valeurs du formulaire (clonées) avant qu'elles ne soient passées au gestionnaire de soumission |
text | FormKitTextFragment | Dispatché lorsqu'une chaîne de caractères générée par FormKit doit être affichée — permettant à i18n ou à d'autres plugins d'intercepter. |
Pour utiliser ces crochets, vous devez enregistrer un middleware de crochet. Un middleware est simplement une fonction qui accepte 2 arguments — la valeur du crochet et next
— une fonction qui appelle le middleware suivant dans la pile et retourne la valeur.
Pour enregistrer un middleware, passez-le au node.hook
que vous souhaitez utiliser :
import { createNode } from '@formkit/core'
const node = createNode()
// Cela transformerait tous les labels en "Different label!"
node.hook.prop((payload, next) => {
if ((payload.prop = 'label')) {
payload.value = 'Different label!'
}
return next(payload)
})
Les crochets peuvent être enregistrés n'importe où dans votre application, mais l'endroit le plus courant où les crochets sont utilisés est dans un plugin.
Les plugins sont le mécanisme principal pour étendre la fonctionnalité de FormKit. Le concept est simple — un plugin est juste une fonction qui accepte un nœud. Ces fonctions sont ensuite automatiquement appelées lorsqu'un nœud est créé, ou lorsque le plugin est ajouté au nœud. Les plugins fonctionnent de manière similaire aux options de configuration — ils sont automatiquement hérités par les enfants et les descendants.
import { createNode } from '@formkit/core'
// Un plugin pour changer la valeur d'une propriété.
const myPlugin = (node) => {
if (node.type === 'group') {
node.props.color = 'yellow'
} else {
node.props.color = 'teal'
}
}
const node = createNode([
plugins: [myPlugin],
children: [createNode()]
])
Dans l'exemple ci-dessus, le plugin est seulement défini sur le parent, mais l'enfant hérite également du plugin. La fonction myPlugin
sera appelée deux fois — une fois pour chaque nœud dans le graphe (qui n'en a que deux dans cet exemple) :
En plus d'étendre et de modifier les nœuds, les plugins jouent un rôle supplémentaire — exposer des bibliothèques d'entrées. Une « bibliothèque » est une fonction assignée à la propriété library
d'un plugin qui accepte un nœud et détermine s'il sait comment « définir » ce nœud. Si c'est le cas, elle appelle node.define()
avec une définition d'entrée.
Par exemple, si nous voulions créer un plugin qui exposait quelques nouvelles entrées : italy
et france
, nous pourrions écrire un plugin pour le faire :
Les développeurs expérimentés remarqueront quelques propriétés intéressantes de ce modèle de bibliothèque de plugin :
node.define()
. Fréquemment, il s'agit simplement de vérifier node.props.type
, mais vous pouvez définir différentes entrées en fonction d'autres conditions, comme si une propriété particulière est définie.Chaque nœud possède son propre magasin de données. Les objets dans ces magasins sont appelés "messages" et ces messages sont particulièrement précieux pour trois cas d'utilisation principaux :
Chaque message (FormKitMessage
en TypeScript) dans le magasin est un objet avec la structure suivante :
{
// Indique si ce message bloque la soumission du formulaire ou non (par défaut : false).
blocking: true,
// Doit être une chaîne de caractères unique (par défaut : chaîne aléatoire).
key: 'yourkey',
// (optionnel) Objet de métadonnées à propos de ce message (par défaut : {}).
meta: {
// (optionnel) Si défini, i18n utilise cela au lieu de la clé pour trouver les messages de la locale.
messageKey: 'i18nKey',
// (optionnel) Si défini, ces arguments seront étalés à la fonction locale i18n.
i18nArgs: [...any],
// (optionnel) Si défini à false, le message vérifiera la localisation.
localize: true,
// (optionnel) La locale du message (par défaut : node.config.locale)
locale: 'en',
// Toute autre métadonnée que vous désirez.
...any
},
// Une catégorie arbitraire à laquelle ce message appartient (à des fins de filtrage).
// Par exemple : 'validation' ou 'success' (par défaut : 'state')
type: string,
// (optionnel) devrait être une chaîne de caractères, un nombre ou un booléen (par défaut : undefined).
value: 'Oups, notre serveur est en panne !',
// Ce message doit-il être montré aux utilisateurs finaux ? (par défaut : true)
visible: true
}
Une fonction d'assistance createMessage({})
peut être importée depuis @formkit/core
pour fusionner vos données de message avec les valeurs par défaut ci-dessus afin de créer un nouvel objet message.
Pour ajouter ou mettre à jour un message, utilisez node.store.set(FormKitMessage)
. Les messages sont ensuite disponibles sur node.store.{messageKey}
import { createMessage, createNode } from '@formkit/core'
const node = createNode()
const message = createMessage({
key: 'clickHole',
value: 'Veuillez cliquer 100 fois.',
})
node.store.set(message)
console.log(node.store.clickHole.value)
// affiche : 'Veuillez cliquer 100 fois.'
Les messages seront automatiquement traduits si le plugin @formkit/i18n
est installé et qu'une clé correspondante est disponible dans la locale active. Lisez la documentation i18n.
L'une des clés de la performance de FormKit est sa capacité à compter efficacement les messages correspondant à des critères donnés (dans le magasin), puis à tenir un compte courant de ces messages à mesure que des modifications sont apportées (y compris depuis les nœuds enfants). Ces compteurs sont créés en utilisant node.ledger
.
Disons que nous voulons compter combien de messages sont actuellement affichés. Nous pourrions le faire en comptant les messages dont la propriété visible
est définie sur true
.
Remarquez que le second argument de node.ledger.count()
est une fonction. Cette fonction accepte un message en argument et attend en retour une valeur booléenne, indiquant si ce message doit être compté ou non. Cela vous permet de créer des compteurs arbitraires pour tout type de message.
Lors de l'utilisation d'un compteur sur un nœud group
ou list
, le compteur se propagera dans l'arbre en additionnant la valeur de tous les messages passant la fonction de critère, puis en suivant ce compte pour les changements dans le magasin.
Le plugin de validation déclare déjà un compteur appelé blocking
qui compte la propriété de blocage de tous les messages. C'est ainsi que les formulaires FormKit savent si tous leurs enfants sont "valides".