
Recientemente encontré una discusión interesante sobre Full Stack Radio:
Bulding Better UI Components with State Machines . El punto era que el concepto de una máquina de estados podría ayudar con el desarrollo de componentes Vue. Comencé a buscar soluciones listas para usar, pero no eran tan simples, y quería hacer una implementación más simple, de lo que quiero hablar en este artículo. El artículo puede ser útil no solo para quienes usan Vue, sino también para usuarios de Angular, React, etc., así como para programadores de otras "denominaciones".
La discusión tocó un tema cercano a todos los que escribieron los componentes. Imagina que está escribiendo un componente que solicita datos y que necesita mostrar el control de giro mientras se ejecuta la consulta. Por lo general, en tales casos, crea una variable booleana isLoading. Inicialmente, isLoading = false, y antes de solicitar datos, establece la variable isLoading en true. Una vez que han llegado los datos, los vuelve a configurar como falsos. La visibilidad de la ruleta está vinculada a isLoading.
Este enfoque funciona muy bien. Pero el componente rara vez es tan simple. Y en el curso del trabajo, todavía es necesario crear variables lógicas que almacenen diferentes estados. El problema es que si tiene una variable de estado, genera dos estados, y dos variables lógicas ya tienen cuatro estados, tres - ocho, etc. Y el problema es que el programador puede cometer un error y no procesar ningún estado en el que pueda entrar el sistema. Y esto lleva a un error. Además, es bastante difícil entender dicho componente y es necesario crear condiciones.
La respuesta es una máquina de estados. El principio es simple: usted describe los estados en los que puede estar el sistema y las transiciones entre los estados. Tener una máquina de este tipo puede evitar muchos errores, así como determinar declarativamente el estado del sistema.
Hay bastantes artículos sobre este tema (por ejemplo,
Máquinas de estado finito en Vue , pero la mayoría de ellos, después de una breve teoría, recomiendan conectar una de las bibliotecas preparadas. Por ejemplo,
davidkpiano / xstate .
Pensé que xstate era demasiado engorroso y quería probar mi bicicleta. Además, esta es una gran razón para descubrir un nuevo patrón para mí.
Aquí está el código para jugar:
máquina de estado con Vue, versión 2 . Y aquí está la versión en bruto, con un enfoque ligeramente diferente:
máquina de estado con Vue, versión 1 .
Partí del artículo
Máquinas estatales .
Entonces la máquina de estados:
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 } }
Inicialízalo así:
const machine = new StateMachine('idle', { idle: ['waitingConfirmation'], waitingConfirmation: ['idle','waitingData'], waitingData: ['dataReady', 'dataProblem'], dataReady: ['waitingConfirmation'], dataProblem: ['waitingConfirmation'] })
En los métodos componentes, cree una función de transición:
transition(nextState, method = null, params = []) { this.machineState = machine.transition(nextState, method, params) }
En los eventos, inmediatamente escribimos a dónde queremos ir:
@click=“transition('waitingConfirmation')"
Si necesita llamar al método componente al mismo tiempo, escriba esto:
@click="transition('waitingData', getData, [222])”
El segundo parámetro es el método componente que debe llamarse con esta transición.
El tercer parámetro es una matriz de variables para este método.
Dentro de los métodos, la llamada es:
this.transition('dataReady')
Deliberadamente no oculté los botones con v-if, solo por ahora, hace que su fuente sea de color gris. Pero está claro que hacer clic en ellos no funciona si la máquina no lo permite.
En general, todo funciona, la solución es muy fácil. Y lo más importante, logramos describir declarativamente la operación del componente. Yo mismo estoy casi listo para aplicar este enfoque en una aplicación real, pero me gustaría entender los pros y los contras de este enfoque y escuchar los consejos de expertos más experimentados.