Vuex review
What is a Vuex
Vuex is a state management mode developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way.
- Vuex is a state management library designed specifically for vue.js
- It stores data that needs to be shared in a centralized manner
- From a usage point of view, it is a JavaScript library
- Its role is to carry out state management, solve complex component communication, data sharing
When is Vuex used
Official documentation: Vuex helps us manage shared state and comes with more concepts and frameworks. This requires weighing short-term and long-term benefits. Using Vuex can be tedious and redundant if you don’t plan to develop large, single-page applications. That’s true — if your application is simple, you’d better not use Vuex. A simple Store pattern is all you need. However, if you need to build a medium to large single-page application, and you’re probably thinking about how to better manage state outside of components, Vuex would be a natural choice. To quote Dan Abramov, the author of Redux, Flux architectures are like glasses: you know when you need them.
When your application has the following requirement scenarios:
-
Multiple views depend on the same state
-
Actions from different views need to change the same state
It is recommended that businesses that fit this scenario use Vuex for data management, such as a very typical scenario: shopping cart.
Note: Vuex should not be abused and should not be used for businesses that do not meet the above requirements. It will only make your application more troublesome.
Simple use of Vuex
Now let’s review how vuex is used. Let’s do an example of adding coins. Okay
The installation
// npm
npm install vuex --save
// yarn
yarn add vuex
Copy the code
Basic configuration
Create a new store folder in the SRC directory and create an index.js file. The following code will then be written.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
coin: 0}})export default store
Copy the code
Store is then introduced in mian.js
import Vue from 'vue'
import App from './App.vue'
import router from './router' / / into the store
import store from './store'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
router,
store, / / store
render: h= > h(App),
}).$mount('#app')
Copy the code
Getters
Vuex allows us to define “getters” (you can think of them as computed properties of the store) in the store. Just like evaluating properties, the return value of a getter is cached based on its dependency and is recalculated only if its dependency value changes.
- Add the getters property to store
const store = new Vuex.Store({
state: {
coin: 0
},
getters: {
getCoin(state) {
return state.coin
}
},
})
Copy the code
- Use getters in components
- Direct use of
<p>Coin: {{$store.getters.getcoin}}</p>
Copy the code
- mapGetters
Vuex provides a way to map getters in a store to evaluate properties
<p>Coin: {{getCoin}}</p>
Copy the code
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['getCoin']),}},Copy the code
Mutations
The method in Mutations is used to change the data of state in the store, and the data in Mutations must be synchronous data.
- Add the Mutations field to the store
The mutations function has two parameters, the first is state in store, and the second is the data sent through store.mit
const store = new Vuex.Store({
state: {
coin: 0
},
getters: {
getCoin(state) {
return state.coin
}
},
mutations: {
commitCoin (state, n) {
state.coin += n
}
},
})
Copy the code
- Use mutations in the component
- Direct use of
<div>
<el-input
v-model="coins"
placeholder="Please enter the number of coins added"
style="width: 300px"
></el-input>
<el-button
type="primary"
@click="addCion"
>Add a coin</el-button>
<p>Coin: {{getCoin}}</p>
</div>
Copy the code
import { mapGetters } from 'vuex'
export default {
data() {
return {
coins: 1}},computed: {
...mapGetters(['getCoin']),},methods: {
addCion() {
// store.commit
this.$store.commit('commitCoin'.Number(this.coins))
}
}
}
Copy the code
$store.mit takes two arguments, the name of the mutations function in store and the argument that needs to be passed into the mutations function.
- mapMutations
import {
mapGetters,
mapMutations,
} from 'vuex'
export default {
data() {
return {
coins: 1}},computed: {
...mapGetters(['getCoin']),},methods: {
...mapMutations(['commitCoin']),
addCion() {
$store.com MIT ('commitCoin', Number(this.coins))
this.commitCoin(Number(this.coins))
}
}
}
Copy the code
Actions
Action is similar to mutation, except that:
- The Action commits mutation rather than a direct state change.
- Actions can contain any asynchronous operation.
- Add actions field to store
const store = new Vuex.Store({
state: {
coin: 0
},
getters: {
getCoin(state) {
return state.coin
}
},
mutations: {
commitCoin (state, n) {
state.coin += n
}
},
actions: {
addCoinSync(context, payload) {
setTimeout(() = > {
context.commit('commitCoin', payload)
}, 1000)}}})Copy the code
- Use actions in the component
- Direct use of
import {
mapGetters,
mapMutations,
} from 'vuex'
export default {
data() {
return {
coins: 1}},computed: {
...mapGetters(['getCoin']),},methods: {
...mapMutations(['commitCoin']),
addCion() {
// this.$store.commit('commitCoin', Number(this.coins))
// this.commitCoin(Number(this.coins))
this.$store.dispatch('addCoinSync'.Number(this.coins))
}
}
}
Copy the code
- mapActions
import {
mapGetters,
mapMutations,
mapActions,
} from 'vuex'
export default {
data() {
return {
coins: 1}},computed: {
...mapGetters(['getCoin']),},methods: {
...mapMutations(['commitCoin']),
...mapActions(['addCoinSync']),
addCion() {
// Equivalent to this.$store.dispatch('addCoinSync', Number(this.coins))
this.addCoinSync(Number(this.coins))
}
}
}
Copy the code
Vuex simulation implementation
Implementation approach
We reviewed the use of Vuex above, and now let’s simulate a Vuex ourselves
- Implementing the install method
- Vuex is a plug-in for Vue, so similar to emulating VueRouter, implement the install method of the Vue plug-in convention first
- To achieve the Store class
- Implement the constructor and receive options
- Reactive processing of state
- The realization of the getter
- Commit and Dispatch methods
let Vue
class Store{
constructor(options) {
this.state = new Vue({
data: options.state
})
this.mutations = options.mutations
this.actions = options.actions
options.getters && this.handleGetters(options.getters)
}
commit = (type, arg) = > {
this.mutations[type](this.state, arg)
}
dispatch(type, arg) {
this.actions[type]({
commit: this.commit,
state: this.state,
}, arg)
}
handleGetters(getters) {
this.getters = {}
// iterate over all keys of getters
Object.keys(getters).forEach(key= > {
// Define several properties for this.getters. These properties are read-only
Object.defineProperty(this.getters, key, {
get: () = > {
return getters[key](this.state)
}
})
})
}
}
// Provide install externally
function install (_Vue) {
Vue = _Vue
Vue.mixin({
beforeCreate() {
// Register store in beforeCreate
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install,
}
Copy the code