Uma máquina de estado simples para VueJS



Recentemente, deparei-me com uma discussão interessante sobre o Full Stack Radio - Bulding Better UI Components com State Machines . O ponto era que o conceito de uma máquina de estado poderia ajudar no desenvolvimento dos componentes do Vue. Comecei a procurar soluções prontas, mas elas não eram tão simples e eu queria fazer uma implementação mais simples, sobre a qual quero falar neste artigo. O artigo pode ser útil não apenas para quem usa o Vue, mas também para usuários do Angular, React etc., bem como para programadores de outras “denominações”.

A discussão abordou um tópico próximo a todos que escreveram os componentes. Imagine. que você está escrevendo um componente que solicita dados e é necessário exibir o girador enquanto a consulta está em execução. Normalmente, nesses casos, você cria uma variável booleana isLoading. Inicialmente, isLoading = false, e antes de solicitar dados, você define a variável isLoading como true. Após a chegada dos dados, você os define novamente como false. A visibilidade do girador está vinculada a isLoading.

Essa abordagem funciona muito bem. Mas o componente raramente é tão simples. E no decorrer do trabalho, ainda é necessário criar variáveis ​​lógicas que armazenam estados diferentes. O problema é que, se você tiver uma variável de estado, ela gera dois estados e duas variáveis ​​lógicas já têm quatro estados, três - oito, etc. E o problema é que o programador pode cometer um erro e não processar nenhum estado em que o sistema possa entrar. E isso leva a um erro. Além disso, é bastante difícil entender esse componente e é necessário criar condições.

A resposta é uma máquina de estado. O princípio é simples - você descreve os estados em que o sistema pode estar e as transições entre os estados. Ter uma máquina dessas pode evitar muitos erros, além de determinar declarativamente o estado do sistema.

Existem muitos artigos sobre esse assunto (por exemplo, Máquinas de Estado Finito no Vue , mas a maioria deles, após uma breve teoria, recomenda conectar uma das bibliotecas prontas. Por exemplo, davidkpiano / xstate .

Eu pensei que o xstate era muito pesado e queria experimentar minha bicicleta. Além disso, esse é um ótimo motivo para criar um novo padrão para mim.

Aqui está o código para jogar - Máquina de estado com Vue, versão 2 . E aqui está a versão bruta, com uma abordagem um pouco diferente - Máquina de estado com Vue, versão 1 .
Comecei no artigo State Machines .

Então a máquina de estado:

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 } } 

Inicialize assim:

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

Nos métodos do componente, crie uma função de transição:

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

Nos eventos, escrevemos imediatamente para onde queremos ir:

 @click=“transition('waitingConfirmation')" 

Se você precisar chamar o método component ao mesmo tempo, escreva isto:

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

O segundo parâmetro é o método do componente que deve ser chamado com essa transição.
O terceiro parâmetro é uma matriz de variáveis ​​para este método.

Dentro dos métodos, a chamada é:

 this.transition('dataReady') 

Eu deliberadamente não ocultei os botões com v-if, por enquanto, deixei a cor da fonte cinza. Mas é claro que clicar neles não funcionará se a máquina não permitir.

Em geral, tudo funciona, a solução é muito fácil. E o mais importante, conseguimos descrever declarativamente a operação do componente. Eu mesmo estou quase pronto para aplicar essa abordagem em um aplicativo real, mas gostaria de entender os prós e contras dessa abordagem e ouvir conselhos de especialistas mais experientes.

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


All Articles