Une machine d'état simple pour VueJS



J'ai récemment rencontré une discussion intéressante sur Full Stack Radio - Bulding Better UI Components with State Machines . Le fait était que le concept d'une machine d'état pourrait aider au développement des composants Vue. J'ai commencé à regarder des solutions prêtes à l'emploi, mais elles n'étaient pas si simples, et je voulais faire une implémentation plus simple, dont je veux parler dans cet article. L'article peut être utile non seulement pour ceux qui utilisent Vue, mais aussi pour les utilisateurs d'Angular, React, etc., ainsi que pour les programmeurs d'autres «dénominations».

La discussion a porté sur un sujet proche de tous ceux qui ont écrit les composants. Imaginez. que vous écrivez un composant qui demande des données et que vous devez afficher le spinner pendant l'exécution de la requête. Habituellement, dans de tels cas, vous créez une variable booléenne isLoading. Initialement, isLoading = false et avant de demander des données, vous définissez la variable isLoading sur true. Une fois les données arrivées, vous les définissez à nouveau sur false. La visibilité Spinner est liée à isLoading.

Cette approche fonctionne très bien. Mais le composant est rarement aussi simple. Et au cours du travail, il est toujours nécessaire de créer des variables logiques qui stockent différents états. Le problème est que si vous avez une variable d'état, elle génère deux états, et deux variables logiques ont déjà quatre états, trois à huit, etc. Et le problème est que le programmeur peut faire une erreur et ne pas traiter les états dans lesquels le système peut entrer. Et cela conduit à une erreur. De plus, il est assez difficile de comprendre un tel composant et il faut créer des conditions.

La réponse est une machine d'état. Le principe est simple - vous décrivez les états dans lesquels le système peut être, et les transitions entre les états. Le fait d'avoir une telle machine peut éviter de nombreuses erreurs et déterminer de manière déclarative l'état du système.

Il y a pas mal d'articles sur ce sujet (par exemple, Finite State Machines dans Vue , mais la plupart d'entre eux, après une brève théorie, recommandent de connecter l'une des bibliothèques prêtes à l'emploi. Par exemple, davidkpiano / xstate .

Je pensais que xstate était trop encombrant et je voulais essayer mon vélo. De plus, c'est une excellente raison de faire ressortir un nouveau modèle pour moi.

Voici le code pour jouer avec - State machine with Vue, version 2 . Et voici la version brute, avec une approche légèrement différente - State machine with Vue, version 1 .
Je suis parti de l'article State Machines .

Donc, la machine d'état:

class StateMachine { constructor (initialState, transitions) { this.state = initialState this.transitions = transitions } transition (nextState, method, params) { const transitionsArray = this.transitions[this.state] if(transitionsArray.indexOf(nextState) === -1) return this.state if(method) method(...params) this.state = nextState return this.state } } 

Initialisez-le comme ceci:

 const machine = new StateMachine('idle', { idle: ['waitingConfirmation'], waitingConfirmation: ['idle','waitingData'], waitingData: ['dataReady', 'dataProblem'], dataReady: ['waitingConfirmation'], dataProblem: ['waitingConfirmation'] }) 

Dans les méthodes des composants, créez une fonction de transition:

 transition(nextState, method = null, params = []) { this.machineState = machine.transition(nextState, method, params) } 

Dans les événements, nous écrivons immédiatement où nous voulons aller:

 @click=“transition('waitingConfirmation')" 

Si vous devez appeler la méthode du composant en même temps, écrivez ceci:

 @click="transition('waitingData', getData, [222])” 

Le deuxième paramètre est la méthode des composants qui doit être appelée avec cette transition.
Le troisième paramètre est un tableau de variables pour cette méthode.

A l'intérieur des méthodes, l'appel est:

 this.transition('dataReady') 

Je n'ai délibérément pas masqué les boutons avec v-if, pour l'instant, leur couleur de police est grise. Mais il est clair que cliquer dessus ne fonctionne pas si la machine ne le permet pas.

En général, tout fonctionne, la solution est très simple. Et surtout, nous avons réussi à décrire de manière déclarative le fonctionnement du composant. Je suis moi-même presque prêt à appliquer cette approche dans une application réelle, mais je voudrais comprendre les avantages et les inconvénients de cette approche, et écouter les conseils d'experts plus expérimentés.

Source: https://habr.com/ru/post/fr482250/


All Articles