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!