Vue state management - Vuex

 vuex official explanation

Vuex is a state management pattern + library developed specifically for Vue.js applications . It uses a centralized storage to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable manner.

easy to understand 

 Vuex is to extract the shared state of components and manage it in a global singleton mode, put the shared data function into vuex, and any component can be used.

When should we use it?

Vuex can help us manage shared state and comes with more concepts and frameworks. This requires a trade-off between short-term and long-term benefits.

Using Vuex can be tedious and redundant if you're not planning to develop a large single-page application. It's true - if your application is simple enough, 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 , you are likely to consider how to better manage the state outside the component, and Vuex will become a natural choice.

 use

1. Install Vex 

npm install --save vuex

2. Configure the Vuex file

Create a new folder store, create a new file index.js, and configure the vuex file in the index.js file—equivalent to a database, but only on the front end. All states (data are placed in state) For example: counter is equivalent to a field in the database, and 0 is the field value.

import { createStore } from "vuex";
// const store = createStore({
// })
// export default store;
//或者简写如下
export default createStore({
    state:{
        counter:0
    }
})

3. Import globally, add the following code to the main.js file, focusing on import and mount.

import store from './store' 
const app = createApp(App);
app.use(store)
app.mount('#app')

4. Read the state in the component, use it in any component page, you can get the value stored in the state

The first

 <p> counter = {
   
   {$store.state.counter}} </p>

 The second is to use the following code in any component page, but it is placed under computed, and computed specifically reads the data of vuex.

<template>
  <p>{
   
   { counter }}</p>
</template>

<script>
import { mapState } from "vuex"
export default {
  computed:{
    //专门读取vuex的数据
    //如有多个 则: ...mapState(["counter",“age"])
    ...mapState(["counter"])
  }
}
</script>

<style>

</style>

 Core idea

There are five states State Getter Mutation Action Module in vuex 

▣State

Provide a unique public data source, all shared data is stored in the state of the store, similar to data

 Define data in state in vuex, which can be called in any component

import Vue from 'vue'
import Vuex from 'vuex'
 
Vue.use(Vuex)
 
export default new Vuex.Store({
  //数据,相当于data
  state: {
    name:"张三",
    age:12,
    count:0
  },
})

 transfer:

method one:

directly in the label

  <p>{
   
   {$store.state.count}}</p>
  <p>{
   
   {$store.state.name}}</p>
  <p>{
   
   {$store.state.age}}</p>

Method Two:

this.$store.state.全局数据名称

Method 3: Import mapstate function from vuex on demand

Note: The global data required by the current component is mapped to the computed property of the current component

<template>
  <p>{
   
   { counter }}</p>
</template>

<script>
import { mapState } from "vuex"
export default {
  computed:{
    //专门读取vuex的数据
    //如有多个 则: ...mapState(["counter",“age"])
    ...mapState(["counter"])
  }
}
</script>

<style>

</style>

▣ Mutation

The only way to change the state in Vuex's store is to submit a mutation. Mutations in Vuex are very similar to events: each mutation has a string event type (type) and a callback function (handler). This callback function is where we actually make the state change, and it accepts state as the first argument:

import { createStore } from "vuex";
// const store = createStore({

// })
// export default store;
//或者简写如下
export default createStore({
    state:{
        //所有状态(数据都放在state中)
        counter:0
    },
    getters:{
        getCount(state){
            return state.counter >0 ?state.counter : "此时的counter<=0"
        }
    },
    mutations:{
        addCount(state){
            state.counter=state.counter+1;
        }
    }
})

 Call method:

<template>
  <h1>主页</h1>
  <p>counter : {
   
   {$store.state.counter}}</p>
  <p>counter : {
   
   {$store.getters.getCount}}</p>
  <p>{
   
   {getCount}}</p>
  <button @click="add">counter++操作</button>
</template>

<script>
import { mapGetters } from "vuex"
export default {
  computed:{
    ...mapGetters(["getCount"])
  },
  methods:{
    add(){
      //固定调用方式
      this.$store.commit("addCount")
    }
  }
}
</script>
<style>
</style>

 Analysis: Any component introduced to counter will get the same change, that is, the counter value is the same. But when a new page is opened, the counter will not get the same change, and the initial value is still obtained from the index file: 0.

Use 2: Passing with parameters

Example: click once, increase by 15

 Example upgrade: the call method is obtained using mapMutations, that is, modify the methods method as follows: the effect is the same.

<template>
  <p>counter : {
   
   {$store.state.counter}}</p>
  <p>counter : {
   
   {$store.getters.getCount}}</p>
  <p>{
   
   {getCount}}</p>
  <button @click="add">counter+15操作</button>
</template>

<script>
import { mapGetters, mapMutations} from "vuex"
export default {
  computed:{
    ...mapGetters(["getCount"])
  },
  methods:{
    ...mapMutations(["addCount"]),
    add(){
      this.addCount(15)
    }
  }
}
</script>

<style>

</style>

Action

Action is similar to Mutation. Mutation cannot perform asynchronous operation. If you want to perform asynchronous operation, you must use Action

Actions submit mutations instead of directly changing the state.

import axios from "axios";
import { createStore } from "vuex";
export default createStore({
    state:{
        //所有状态(数据都放在state中)
        counter:0
    },
    getters:{
        getCount(state){
            return state.counter >0 ?state.counter : "此时的counter<=0"
        }
    },
    mutations:{
        addCount(state,num){
            state.counter += num;
        }
    },
    actions:{
        //({}) 加上花括号代表对象结构赋值
        asyncAdd({commit}){
            axios.get("http://iwenwiki.com/api/FingerUnion/list.php")
            .then(res => {
                commit("addCount",res.data[0])
            })
        }
    }
})

Call method one:

<template>
  <p>counter : {
   
   {$store.state.counter}}</p>
  <p>counter : {
   
   {$store.getters.getCount}}</p>
  <p>{
   
   {getCount}}</p>
  <button @click="add">counter+15操作</button>
  <button @click="addAsyn">异步增加counter操作</button>
</template>
<script>
import { mapGetters, mapMutations} from "vuex"
export default {
  computed:{
    ...mapGetters(["getCount"])
  },
  methods:{
    ...mapMutations(["addCount"]),
    addAsyn(){
      this.$store.dispatch("asyncAdd")
    },
    add(){
      //固定调用方式
      // this.$store.commit("addCount",15)
      this.addCount(15)
    }
  }
}
</script>
<style>
</style>

 Call method 2: use mapMutations to obtain, that is, modify the methods method after introduction as follows: the effect is the same

tips: ({}) plus curly braces represent object structure assignment

Getter 

Filter data in vuex.

Similar to computed in vue, it is cached and processed to form new data for the data in the store .

 The first

import { createStore } from "vuex";
// const store = createStore({

// })
// export default store;
//或者简写如下
export default createStore({
    state:{
        //所有状态(数据都放在state中)
        counter:0
    },
    getters:{
        getCount(state){
            return state.counter >0 ?state.counter : "此时的counter<=0"
        }
    }
})

 Call method one:

 <p> counter : {
   
   {$store.getters.getCount}} </p>

 Call method two: use mapGetters

<template>
  <p>{
   
   {getCount}}</p>
</template>

<script>
import { mapGetters } from "vuex"
export default {
  computed:{
    ...mapGetters(["getCount"])
  }
}
</script>
<style></style>

result:

Modules

When encountering a large-scale project with a large amount of data, the store will appear bloated

To solve the above problems, Vuex allows us to split the store into modules . Each module has its own state, mutation, action, getter, and even nested submodules—separated in the same way from top to bottom:

 Quote:

this.$store.state.cityModules.cityname

Guess you like

Origin blog.csdn.net/qq_45947664/article/details/127660917