Introduction
Whenever an application is created, it is simple to manage, but as time goes, when more features are added to the application, the app becomes more and more complex.
The same goes with the frontend, as when the code size increases, the number of bugs also increases.
We have State management in Vue to solve this problem, which uses Vuex. Further in the blog, we will learn more about them.
State Management from Scratch
State management refers to implementing a design pattern that manages the states of one or more user interfaces and combines them into one state to use them application-wide.
It is beneficial for maintaining cleaner apps and is also perfect for large applications because of the single state or the source of truth.
In Vue applications, the source of truth is often overlooked, reactive data.
You need to make your objective reactive to make your single piece of state to be shared by multiple instances, and you can make your object reactive as same as done below:
const { createApp, reactive } = Vue
const sourceOfTruth = reactive({
message: 'Making Reactive'
})
const appX = createApp({
data() {
return sourceOfTruth
}
}).mount('#app-x')
const appY = createApp({
data() {
return sourceOfTruth
}
}).mount('#app-y')
<div id="app-a">App X: {{ message }}</div>
<div id="app-b">App Y: {{ message }}</div>
Explanation
In the above-stated example, we are creating two apps named X and Y, respectively, and both are returning the souceofTruth. Here sourceofTruth refers to the message that we are providing.
And the mount function attaches the element to the DOM.
Both appX and Y will automatically update their views when sourceofTruth is mutated.
Although we have a single source of truth now, debugging will be difficult. Any part of our app can change any piece of data without leaving a trace.:
const appY = createApp({
data() {
return sourceOfTruth
},
mounted() {
sourceOfTruth.message = 'changing message' // both apps will render 'changing message' message now
}
}).mount('#app-b')
We can adopt a store pattern to solve this problem:
const store = {
debug: true,
state: reactive({
message: 'Hi!'
}),
setMessageAction(newValue) {
if (this.debug) {
console.log('setMessageAction triggered with', newValue)
}
this.state.message = newValue
},
clearMessageAction() {
if (this.debug) {
console.log('clearMessageAction triggered')
}
this.state.message = ''
}
}
Inside the Store, we have put all the actions that can mutate its state. This makes it easy to understand the type of mutation that can be triggered. This is the type of centralized state management. Now we will have a log to find if anything happened and the reasons for the bug.
Each component can still manage and own its own private state:
<div id="app-x">{{sharedState.message}}</div>
<div id="app-y">{{sharedState.message}}</div>
const appX = createApp({
data() {
return {
privateState: {},
sharedState: store.state
}
},
mounted() {
store.setMessageAction('Changed!')
}
}).mount('#app-x')
const appY = createApp({
data() {
return {
privateState: {},
sharedState: store.state
}
}
}).mount('#app-y')
The state management uses Vuex, a centralized store for all the application's components. It is a library + state management pattern.
Now we will learn about state management patterns.