XState tools for Vue
npm install xstate-vue2> Vue 2 composables for xstate and @xstate/fsm
- Quick Start
- API
- useMachine(machine, options?)
- useService(service)
- useActor(actor, getSnapshot)
- useInterpret(machine, options?, observer?)
- useSelector(actor, selector, compare?, getSnapshot?)
- useMachine(machine) with @xstate/fsm
- Configuring Machines
- Matching States
- Persisted and Rehydrated State
1. Install xstate (or @xstate/fsm) andxstate-vue2
``bash`
npm i xstate xstate-vue2
2. Import the useMachine composition function:
`vue
`
A Vue composition function that interprets the given machine and starts a service that runs for the lifetime of the component.
Arguments
- machine - An XState machine.options
- (optional) - Interpreter options OR one of the following Machine Config options: guards, actions, activities, services, delays, immediate, context, or state.
Returns { state, send, service}:
- state - Represents the current state of the machine as an XState State object.send
- - A function that sends events to the running service.service
- - The created service.
A Vue composition function that subscribes to state changes from an existing service.
Arguments
- service - An XState service.
Returns {state, send}:
- state - Represents the current state of the service as an XState State object.send
- - A function that sends events to the running service.
A Vue composition function that subscribes to emitted changes from an existing actor.
_Since 0.5.0_
Arguments
- actor - an actor-like object that contains .send(...) and .subscribe(...) methods.getSnapshot
- - a function that should return the latest emitted value from the actor.actor.state
- Defaults to attempting to get the , or returning undefined if that does not exist.
`js
import { useActor } from 'xstate-vue2';
export default {
props: ['someSpawnedActor'],
setup(props) {
const { state, send } = useActor(props.someSpawnedActor);
return { state, send };
}
};
`
A Vue composition function that returns the service created from the machine with the options, if specified. It also sets up a subscription to the service with the observer, if provided.
_Since 0.5.0_
Arguments
- machine - An XState machine or a function that lazily returns a machine.options
- (optional) - Interpreter options and/or any of the following machine config options: guards, actions, services, delays, immediate, context, state.observer
- (optional) - an observer or listener that listens to state updates:{ next: (state) => {/ ... /} }
- an observer (e.g., )(state) => {/ ... /}
- or a listener (e.g., )
`js`
import { useInterpret } from 'xstate-vue2';
import { someMachine } from '../path/to/someMachine';
export default {
setup() {
const service = useInterpret(someMachine);
return service;
}
};
With options + listener:
`js`
import { useInterpret } from 'xstate-vue2';
import { someMachine } from '../path/to/someMachine';
export default {
setup() {
const service = useInterpret(
someMachine,
{
actions: {
/ ... /
}
},
(state) => {
// subscribes to state changes
console.log(state.value);
}
);
// ...
}
};
A Vue composition function that returns the selected value from the snapshot of an actor, such as a service. This hook will only cause a rerender if the selected value changes, as determined by the optional compare function.
_Since 0.6.0_
Arguments
- actor - a service or an actor-like object that contains .send(...) and .subscribe(...) methods.selector
- - a function that takes in an actor's "current state" (snapshot) as an argument and returns the desired selected value.compare
- (optional) - a function that determines if the current selected value is the same as the previous selected value.getSnapshot
- (optional) - a function that should return the latest emitted value from the actor.actor.state
- Defaults to attempting to get the , or returning undefined if that does not exist. Will automatically pull the state from services.
`js`
import { useSelector } from '@xstate/vue';
const selectCount = (state) => state.context.count;
export default {
props: ['service'],
setup(props) {
const count = useSelector(props.service, selectCount);
// ...
return { count };
}
};
With compare function:
`js`
import { useSelector } from '@xstate/vue';
const selectUser = (state) => state.context.user;
const compareUser = (prevUser, nextUser) => prevUser.id === nextUser.id;
export default {
props: ['service'],
setup(props) {
const user = useSelector(props.service, selectUser, compareUser);
// ...
return { user };
}
};
With useInterpret(...):
`js`
import { useInterpret, useSelector } from '@xstate/vue';
import { someMachine } from '../path/to/someMachine';
const selectCount = (state) => state.context.count;
export default {
setup() {
const service = useInterpret(someMachine);
const count = useSelector(service, selectCount);
// ...
return { count, service };
}
};
A Vue composition function that interprets the given finite state machine from [@xstate/fsm] and starts a service that runs for the lifetime of the component.
Arguments
- machine - An XState finite state machine (FSM).
Returns an object {state, send, service}:
- state - Represents the current state of the machine as an @xstate/fsm StateMachine.State object.send
- - A function that sends events to the running service.service
- - The created @xstate/fsm service.
Example (TODO)
Existing machines can be configured by passing the machine options as the 2nd argument of useMachine(machine, options).
Example: the 'fetchData' service and 'notifySuccess' action are both configurable:
`vue
Searching...
Success! {{ state.context.data }}
{{ state.context.error.message }}
`
For hierarchical and parallel machines, the state values will be objects, not strings. In this case, it's better to use state.matches(...):
`vue`
You can persist and rehydrate state with useMachine(...) via options.state:
`vue``