Vuex, Flux for Vue.js
data management in Vue.js apps
As is
Is this a problem ?
Possible Solutions
Store pattern
Global event bus
import Vue from 'vue';
let bus = new Vue();
export default bus;
import bus from '../../Shared/EventBus.vue';
// in component A:
bus.$on('some-event', callback)
// in component B:
bus.$emit('some-event')
EventBus
Components
Flux architecture
Flux is an architecture that Facebook uses internally when working with React. It is not a framework or a library. It is simply a new kind of architecture that complements React and the concept of Unidirectional Data Flow.
Vuex
flux for vue.js
What is Vuex?
Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.
image source mazarin.lk
Installing vuex
<script src="/path/to/vue.js"></script> <script src="/path/to/vuex.js"></script>
npm install vuex --save
yarn add vuex
Vuex parts
Vuex Store
import Vuex from ‘vuex
const store = new Vuex.Store({
state: {…},
getters: {…},
mutations: {…},
actions: {…}
})
new Vue({
store, render: h => h(App)
}).$mount('#app')
Vuex - State
Vuex uses a single state tree - that is, this single object contains all your application level state and serves as the "single source of truth". This also means usually you will have only one store for each application.
Vuex - State
import Vuex from 'vuex'
const store = new Vuex.Store( {
state: {
todos: []
}
})
const app = new Vue({ el: '#app', store })
Vuex - Getters
The mapGetters helper simply maps store getters to local computed properties.
You can think of Getters as computed properties for stores.
Getter's result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.
Vuex - Getters
const store = new Vuex.Store({
state: {},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}}})
import { mapGetters } from 'vuex'
export default {
computed: { ...mapGetters(['doneTodos'])
}}
Vuex - Mutations
The only way to actually change state in a Vuex store is by committing a mutation.
Vuex mutations must be synchronous!
Vuex - Mutations
const store = new Vuex.Store({ mutations: {
increment (state, n){ state.count += n }
} })
this.$store.commit('increment', 10)
Commit with Payload
Vuex - Mutations
Committing Mutations in Components
You can commit mutations in components with this.$store.commit('xxx'), or use the mapMutations helper which maps component methods to store.commit calls
import { mapMutations } from 'vuex' export default { methods: { ...mapMutations(['increment')] }
Vuex - Mutations
When we mutate the state, Vue components observing the state will update automatically.
1. Prefer initializing your store's initial state with all desired fields upfront.
2. When adding new properties to an Object, you should either:
Use Vue.set(obj, 'newProp', 123),
or
state.obj = { ...state.obj, newProp: 123 }
Vuex - Actions
Actions are similar to mutations, the differences being that:
- Instead of mutating the state, actions commit mutations.
- Actions can contain arbitrary asynchronous operations.
Action handlers receive a context object which exposes the same set of methods/properties on the store instance, so you can call context.commit to commit a mutation, or access the state and getters via context.state and context.getters
Vuex - Actions
const store = new Vuex.Store({
state: {count: 0},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}}
})
Vuex - Actions
this.$store.dispatch('incrementAsync')
Dispatching Actions
We can perform asynchronous operations inside an action.
actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) } }
Vuex - Actions
Dispatching Actions in Components
You can dispatch actions in components with this.$store.dispatch('xxx'), or use the mapActions helper which maps component methods to store.dispatch calls
import { mapActions } from 'vuex' export default { methods: { ...mapActions(['increment')] }
Vuex - Modules
Vuex - Plugins
Vuex - Testing
maybe next time ...
Vuex - Form Handling
Vuex recap
const store = new Vuex.Store({
state: {…}, // absolute truth
getters: {…},
mutations: {…}, // sync
actions: {…} // async
})
mapState
mapGetters
mapMutations
mapActions
inside components
Thank you
@imhotepp
Q&A
workshop 3 - Vuex is Flux for Vue.js
By Dragosh
workshop 3 - Vuex is Flux for Vue.js
- 474