0.1.0 • Published 6 years ago
vue-easy-state-machine v0.1.0
vue-easy-state-machine
Light state machine packaged as a vue component
Installation
$ npm install vue-easy-state-machineOverview
This packages provides a <easy-state-machine> component managing a small state machine for UI management
Usage
Declare as Vue plugin:
import VueEasyStateMachine from "vue-easy-state-machine";
Vue.use(VueEasyStateMachine);In your component <script> section, declare your state table with states & associated behavior:
export default {
data() {
return {
states: {
askEmail: {
entry: true,
success: "askPassword",
failure: "askEmail"
},
askPassword: {
success: "login",
failure: "askEmail"
},
login: {
success: this.initSession,
failure: "askEmail"
},
//...
stateXXX: {
success: "stateYYY",
failure: "stateZZZ"
}
//...
}
};
},
methods: {
initSession() {
//...
}
}
};In your component <template> section, wrap the state machine around components related to each state:
- State table is provide through
statesprop. - Each declared state value is available through
#defaultvariable, incurrentarray; Only the active state is set totrue, all other are set tofalse. easy-state-machinecomponent exposessuccess()andfailure()methods to trigger evolution; You can userestart()to ... restart.
<easy-state-machine :states="states" #default="state">
<div v-if="state.current.askEmail">
<input type="email" placeholder="Email" />
<button type="button" @click="state.success">Next</button>
</div>
<div v-if="state.current.askPassword">
<input type="password" placeholder="Password" />
<button type="button" @click="state.success">Next</button>
<button type="button" @click="state.failure">Previous</button>
</div>
<div v-if="state.current.login">
<strong>You are logged</strong>
<button type="button" @click="state.success">Init Session</button>
<button type="button" @click="state.failure">Restart</button>
</div>
</easy-state-machine>And that's it !
State Table Advanced Configuration
Each state can handle following items:
{
"entry": true,
"onEnter" : () => {},
"success": "stateXXX",
"failure": "stateYYY",
"onLeave" : () => {},
}entry
- Type:
Boolean - Default:
false - Details: Indicates state to start with
- Restrictions: Only one
trueentry per state table. If multiple entries, only the first one is taken.
success
- Type:
StringorFunction - Default:
undefined - Details: Indicates state to go to in case of successful operation at current state. Can be a function returning state name.
- Restrictions: Will trigger state machine error if pointing nowhere....
failure
- Type:
StringorFunction - Default: value of
successentry - Details: Indicates state to go to in case of failed operation at current state. Can be a function returning state name.
- Restrictions: Will trigger state machine error if pointing nowhere...
onEnter
- Type:
Function - Default:
undefined - Details: Function to call on state arrival
- Restrictions: Must be current component functions, not called if empty
onLeave
- Type:
Function - Default:
undefined - Details: Function to call on state leaving
- Restrictions: Must be current component functions, not called if empty
Advanced usage & Tips
Complex branching
You can manage complex branching with success and failure functions:
{
"success": () => { return this.myBooleanValue ? 'stateXXX' : 'stateYYY' },
"failure": this.myBranchingFunction,
}Where myBranchingFunction is defined in methods block:
methods: {}
myBranchingFunction() {
if ( /** my test **/ )
return 'stateXXX';
else
return 'stateYYY';
}
}Events
stateChange
- When: On each state change, after
onLeaveand beforeonEnterare called - First argument: previous state name
- Second argument: next state name
Transitions
You can use with <transition> for a beautiful effect:
<easy-state-machine :states="states" #default="state">
<transition
name="transition-login"
enter-active-class="animated fadeIn"
leave-active-class="animated fadeOut"
mode="out-in"
>
<div v-if="state.current.askEmail" key="askEmail">
...
</div>
<div v-if="state.current.askPassword" key="askPassword">
...
</div>
<div v-if="state.current.login" key="login">
...
</div>
</transition>
</easy-state-machine>Validating/Testing
Sample application provided in sample direcory for testing purpose:
$ npm run sampleAdd then open ./sample/index.html in your browser