As with Redux, when you don’t know if you need itVuexNo. Don’t use Vuex just because you want to use it.
As anyone who has used Vue knows, Vuex is a global state management module of Vue. Its function is that multiple components share state and data. When one component changes the global state, another component bound to the state also responds. A Vue can actually be thought of as a function, with a data broker in scope that can be read and written to in each instance of the Vue
We all know that Vue’s data-driven principle is to use Object.defineProperty() to proxy data and asynchronously respond to data-bound views in setters (vue3.0 uses proxy).
Vuex is a new Vuex property that can be applied to Vuex by mixing Vuex’s beforeCreate hook with mixin and registering $store in init
In order to make the case more concrete, I used scaffolding to build a projectAnother article), although there are only two components, I can clearly understand their usage. My SRC directory is as follows, except the most basic app.vue and main.js, there are only two components and a store
The first component is the input field, where characters are entered and displayed in two component divs. That’s it
To implement this, we need to create a vUE instance in MainJS and register it in vUE to emit and on events for component communication
main.js
import Vue
from 'vue'
import App
from './App'
Vue.prototype.$eventBus = new Vue()
new Vue({
el: '#app'.components: {App},
template: '<App/>'
})
Copy the code
inputComp.vue
<template>
<input type="text" @input="inputHandler" />
</template>
<script>
export default {
name: "inputComp".methods: {
inputHandler(e) {
this.$eventBus.$emit('changeVal',e.target.value)// Messages are sent via eventBus on input,}}};</script>
<style
scoped>
</style>
Copy the code
divComp.vue
<template>
<div>
{{
val
}}
</div>
</template>
<script>
export default {
name: "divComp",
data () {
return {
val: ' '
}
},
mounted () {
this.$eventBus.$on('changeVal'.(e) = > {// Listen for input events to pass information through eventBus
this.val = e
})
}
}
</script>
<style
scoped>
</style>
Copy the code
The effect is as follows:
Now I’m going to go step by step how is Vuex used in this case
First we add state to store data values (similar to data in the component), add a state in Store, and store in main
import Vue
from "vue";
import Vuex
from "vuex";
Vue.use(Vuex);
const state = {
val: ' '
}
export default new Vuex.Store({
state
})
Copy the code
Then change eventBus to the following code in the inputHandler above
inputHandler(e) {
this.$store.state.val = e.target.value;
}
Copy the code
Replace val with this.$store.state.val. This is the simplest way to use Vuex. Just change state to achieve global state. If your project is not complex, this simple global state will suffice
Next, we add a mutations, where we can treat mutations as the publishing/subscription scheduling center. Writing the function in mutations is equivalent to registering an event, and adding mutations in the store can be triggered through emit on the page
const state = {
val: ' '
}
const mutations = {
changeVal (state, _val) {
state.val = _val
}
}
export default new Vuex.Store({
state,
mutations
})
Copy the code
Call this function in inputHandler, where changeVal is the name of the function on Mutations, which uses emit arguments to achieve and publish/subscribe
this.$store.commit('changeVal',e.target.value)
Copy the code
Understanding mutations, let’s look at Getters. We all know that there is a computed property in Vue, which will be recalculated when the value of the agent changes. The derived property getters in Vuex will bind some or some values in State, and filter the values by passing parameters. The role of modification
Here we do a simple calculation. After entering a character, calculate its length and concatenate it. In inputHandler, the operation remains unchanged, and in Store we add getters
import Vue
from "vue";
import Vuex
from "vuex";
Vue.use(Vuex);
const state = {
val: ' '
}
const mutations = {
changeVal (state, _val) {
state.val = _val
}
}
const getters = {
getValueLength (state) {
return ` length:${state.val.length}`}}export default new Vuex.Store({
state,
mutations,
getters
})
Copy the code
Then in this div tags. $store. State. Val added after this. $store. Getters. GetValueLength
<div>
{{
this.$store.state.val+this.$store.getters.getValueLength
}}
</div>
Copy the code
The effect is as follows:
If you’re still having trouble getting to this point, congratulations, you’ve got the better part of the Vuex
Next, we will talk about Actions. Before we talk about Actions, we will review mutations, which register some events and trigger them through emit in the component to handle asynchronous and decouple. Actions are similar to mutation, except for 1. The actions submitted by mutation do not directly change the state. 2.Action can contain any asynchronous operation.
That is to say, we want to put the EMIT action in actions, and in some way trigger the actions function to call emit indirectly. In this case, to make the action more intuitive, we add a method to clear the input field characters. Clear state.val when the Clear button is clicked. Bind value to state in the input box component
<template>
<input type="text" @input="inputHandler" :value="this.$store.state.val" />
</template>
<script>
export default {
name: "inputComp".methods: {
inputHandler(e) {
this.$store.dispatch("actionVal", e.target.value); ,}}};</script>
<style
scoped>
</style>
Copy the code
Add a delete button to another component that displays data and bind the delete event, notify the Store via Dispatch and emit state
<template>
<div>
<button @click="clickHandler">remove</button>
<span>{{ this.$store.state.val + this.$store.getters.getValueLength }}</span>
</div>
</template>
<script>
export default {
name: "divComp".methods: {
clickHandler(){
this.$store.dispatch('actionClearVal')}}};</script>
<style
scoped>
</style>
Copy the code
Finally, create actions and mutations for deletion in the store
import Vue
from "vue";
import Vuex
from "vuex";
Vue.use(Vuex);
const state = {
val: ' '
}
const mutations = {
changeVal(state, _val) {
state.val = _val
},
clearVal(state, _val) {
state.val = ' '}}const actions = {
actionVal(state, _val) {
state.commit('changeVal', _val)
},
actionClearVal(state) {
state.commit('clearVal')}}const getters = {
getValueLength(state) {
return ` length:${state.val.length}`}}export default new Vuex.Store({
state,
mutations,
actions,
getters
})
Copy the code
The final effect is as follows:
This concludes the basic usage of Vuex.
In addition, however, Vuex official also provides auxiliary function (mapState mapMutations, mapGetters, mapActions) and Modules (store module, when there are many global state, we in order to avoid code bloat, We can divide stores into modules
Let’s re-implement the above functionality using helper functions
Input box:
<template>
<input type="text" @input="inputHandler" :value="value" />
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
name: "inputComp".computed: {
...mapState({ value: "val"})},methods: {
...mapMutations({ sendParams: "changeVal" }), // sendParams is used to pass parameters, register sendParams on mutations, and trigger sendParams when it is entered
inputHandler(e) {
this.sendParams(e.target.value); ,}}};</script>
<style
scoped>
</style>
Copy the code
Display frame:
<template>
<div>
<button @click="clickHandler">remove</button>
<span>{{ value + valueLength }}</span>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from "vuex";
export default {
name: "divComp".computed: {
...mapState({ value: "val" }),
...mapGetters({ valueLength: "getValueLength"})},methods: {
...mapActions({ clickHandler: "actionClearVal"})}};</script>
<style
scoped>
</style>
Copy the code
One thing to note here is the pass-through of mapActions and mapMutations, where I use another function to receive the parameters and register them in the Store
Modules will not be introduced here, the official has given a detailed explanation
Finally, attach the address of the case, you can help yourself if necessary, thank you for reading the last, if this article is helpful to you, please help to support, thank you very much!