The back-end programmer teaches himself the front-end notes

Introduction to the

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 manner.

Simply put, Vuex is like a front end database or cache, no matter what page, as long as there is data in Vuex, you can go to get.

Vuex is divided into five parts:

  • State: is the data source that stores data
  • Getters: You can get the State data and then custom assembly returns the new data
  • Mutations: Can change the data of State, and the proposed method implementation is synchronous
  • Actions: Can execute the method in Mutations asynchronously
  • Modules: Each Module has its own State, Getters, Mutations and Actions

These five parts complement each other.

TypeScript using

Execute commands in the vue project root directory to install the VUex module

npm install vuex@next --save
Copy the code

/ SRC /store/store.ts and then define the InjectionKey and store

import { InjectionKey } from 'vue'
import { createStore, useStore as baseUseStore, Store } from 'vuex'

// Define the interface for the State data type
interface IState{
}

// Type passing
export const key: InjectionKey<Store<IState>> = Symbol(a)export const store = createStore<IState> ({ 
})

// Used in the composite API setup() to save passing the key every time
export function useStore() {
    return baseUseStore(key)
}
Copy the code

Then use the vuex defined above in the main.ts file

import { createApp } from 'vue'
import App from './App.vue'
import { store,key } from './store/store'

createApp(App)
.use(store,key)
.mount('#app')
Copy the code

State

State is where the data source is stored, so we can store our data here, so if I define a name field here, I need to add a definition data type to the interface IState

interface IState{
    name: string
}
Copy the code

Then add data to the createStore

export const store = createStore<IState> ({ 
    state: {name: 'ooooooh is gray'}})Copy the code

Now that the data is defined, the next step is to access the data on the page. There are two ways to access the data in Vuex

Composite API access

In the composite API, we can access vuex data directly by importing the useStore() method we just defined in/SRC /store/store.ts

import { defineComponent } from 'vue';
import { useStore } from './store/store'

export default defineComponent({

  setup(){
    let store = useStore()
    // Access the name data in state
    console.log(store.state.name)
  }
});
Copy the code

Running the code will print ooooOOH gray in the console

. ToRefs () accesses all fields

If you want to access it from the page, you can use… ToRefs () to directly expand all the fields in store.state, and then directly access the fields in vuex state on the page

// App.vue <template> <div> {{ name }} </div> </template> <script lang="ts"> import { defineComponent, toRefs} from 'vue'; Import {useStore} from './store/store' export default defineComponent({setup(){let store = useStore() return {// expand State all fields... toRefs(store.state) } } }); </script> <style> </style>Copy the code

Reactive Aggregates a single field

If you want to import a single piece of data, you can simply add it to reactive data

import { defineComponent, reactive, toRefs} from 'vue';
  import { useStore } from './store/store'

  export default defineComponent({
    
    setup(){
      let store = useStore()
    	// Make vuex's state data into reactive
      let params = reactive({
        name: store.state.name
      })
      return {
        ...toRefs(params),
      }
    }
  });
Copy the code

Computed accesses a single field

You can also use the Computed module to access data by importing the Computed module in vUE first

// App.vue <template> <div> {{ name }} </div> </template> <script lang="ts"> import { defineComponent, computed} from 'vue'; import { useStore } from './store/store' export default defineComponent({ setup(){ let store = useStore() return { name:  computed(()=>store.state.name) } } }); </script> <style> </style>Copy the code

Getters

The methods in getters are defined in vuex/types/index.d.ts

export type Getter<S, R> = (state: S, getters: any, rootState: R, rootGetters: any) = > any;
Copy the code

It has four parameters, which are state, getters, rootState, and rootGetters

State can retrieve data from the same level as state, and getters can retrieve data from other methods of getters in the same level

RootState and rootGetters can retrieve the rootState and gatters data when the current Getters is in the module

For example, we can wrap a variable in state into a single sentence and return:

export const store = createStore<IState> ({ 
    state: {name: 'ooooooh is gray',},getters:{
        newName(state):string{
          	// Use state to access the name field
            return 'Hello! I was: '+state.name
        }
    }
})
Copy the code

When we want to access other getters, we can do this:

export const store = createStore<IState> ({ 
    state: {name: 'ooooooh is gray'.age: 20
    },
    getters:{
        hello(state,getters):string{
          	// Access other getters via getters
            return 'Hello! I was: '+state.name+', '+getters.ageInfo
        },
        ageInfo(state):string{
            return 'Age:'+state.age
        }
    }
})
Copy the code

Composite API access

We can access the methods in gatters in the composite API the same way we access the data in state:

import { defineComponent } from 'vue';
import { useStore } from './store/store'

export default defineComponent({

  setup(){
    let store = useStore()
    // Access the hello method in getters
    console.log(store.getters.hello)
  }
});
Copy the code

In addition, getters can also use… ToRefs (), computed

<template> <div> {{ hello }} </div> </template> <script lang="ts"> import { defineComponent, computed, toRefs } from 'vue'; Import {useStore} from './store/store' export default defineComponent({setup(){let store = useStore() return {// Pass Computed (()=>store.getters. Hello), // Through... ToRefs () access //... toRefs(store.getters), } } }); </script> <style> </style>Copy the code

Mutations

Mutations, which provides a way to change the data in state, is defined in VUex /types/index.d.ts:

export type Mutation<S> = (state: S, payload? :any) = > any;
Copy the code

The payload is a custom parameter passed in. There is a question mark after it, indicating that it is optional

So when we want to change the value of the state field, we can write code in store.ts like this:

export const store = createStore<IState> ({ 
    state: {name: 'ooooooh is gray',},mutations: {changeName(state){
            // Change the value of name in state
            state.name = 'greycode'}}})Copy the code

To customize the parameters passed in, write:

export const store = createStore<IState> ({ 
    state: {name: 'ooooooh is gray',},mutations: {changeName(state,newName:string){
            // Pass in the custom field and set
            state.name = newName
        }
    }
})
Copy the code

Composite API access

In a composite API, we can commit this method with the commit:

import { defineComponent } from 'vue';
import { useStore } from './store/store'

export default defineComponent({

  setup(){
    let store = useStore()
    let change = () = > {
      // Submit the changeName method for mutations
      // store.commit('changeName')
      
      // Submit and execute the changeName method in mutations, and pass in the custom parameters
      store.commit('changeName'.'Custom')}return {
      change
    }
  }
});
Copy the code

. mapMutations

We can use it directly in the composite API… MapMutations to get the method in mutations, and then call that method directly on the page

  import { defineComponent } from 'vue';
  import { mapMutations } from 'vuex';
  import { useStore } from './store/store'

  export default defineComponent({
    
    setup(){
      let store = useStore()
      return {
        / / use... MapMutations to get the method that's involved in mutations. mapMutations(['changeName'])}}});Copy the code

Then use it directly in the page:

<template> <div> <button type="button" @click="changeName"> </button> <! <button type="button" @click="changeName(' custom name ')"> </button> </div> </template>Copy the code

Action

Action is used when the data in state is changed asynchronously, but instead of directly changing the data in state, it changes the data in state indirectly through the methods in mutations, which are asynchronously performed

It is defined in vuex/types/index.d.ts as follows:

export type Action<S, R> = ActionHandler<S, R> | ActionObject<S, R>;
Copy the code

It supports two types of data, an ActionHandler<S, R> and an ActionObject<S, R>. Actionobjects are usually used in the namespace of a Module. They are defined as follows:

export type ActionHandler<S, R> = (this: Store<R>, injectee: ActionContext<S, R>, payload? :any) = > any;

export interfaceActionObject<S, R> { root? :boolean;
  handler: ActionHandler<S, R>;
}
Copy the code

I’ll just talk about ActionHandler here; the other one will wait for the Module.

In ActionHandler, it takes three parameters: this, injectee, and Payload. This is the entire Store, injectee is the context of the current Action. Payload is an incoming parameter that can be customized

So we can use it like this:

export const store = createStore<IState> ({ 
    state: {name: 'ooooooh is gray'
    },

    mutations: {changeName(state){
            state.name = 'Asynchronous renaming'}},actions: {asyncChange(ctx){
          // Change the name after two seconds
          setTimeout(() = >{
            ctx.commit('changeName')},2000)}}})Copy the code

Composite API access

With the actions defined, we can dispatch the action in the composite API:

import { defineComponent } from 'vue';
import { useStore } from './store/store'

export default defineComponent({

  setup(){
    let store = useStore()
    let syncChange = () = > {
      // Execute the asyncChange method in actions
      store.dispatch('asyncChange')}return {
      syncChange
    }
  }
});
Copy the code

. mapActions

You can also use… MapActions to get methods directly from actions:

import { defineComponent } from 'vue';
import { mapActions } from 'vuex';
import { useStore } from './store/store'

export default defineComponent({

  setup(){
    let store = useStore()
    return {
      ...mapActions(['asyncChange'])}}});Copy the code

The same as mutation is used on the page, just access the method name in the Actions:

< span style =" box-sizing: border-box; color: RGB (74, 74, 74); line-height: 22px; font-size: 13px! Important; word-break: inherit! Important;"Copy the code

The last

In addition, there is a Module Module, but generally small projects do not use and more content, learn next time.