Vue learning -Vuex state management

All variables shared by multiple components are stored in one object, which is then placed in a top-level Vue instance for other components to use – centralized state management

Self-wrapped objects are not responsive (vue.prototype.shareobj)

What is Vuex? | Vuex (vuejs.org)

Manage what state?

  • Such as user login status, user name, profile picture, location information and so on

  • For example, the collection of goods, physics in the shopping cart, and so on

  • All of this state information can be stored and managed in a single place, and it’s responsive

Vuex- State switch from single screen to multiple screens

A single interface

Multiple interface

Demo

index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    // Store the share status
    state: {
        counter: 1000
    },
    // Change the state method of the share
    mutations: {
        // The default parameter is state
        increment(state) {
            state.counter++;
        },
        decrement(state){ state.counter--; }},actions: {},
    getters: {},modules: {}})Copy the code

App.vue

<template>
  <div id="app">
    <h2>{{ message }}</h2>
    <h2>{{ $store.state.counter }}</h2>
    <button @click="addition">+</button>
    <button @click="substraction">-</button>

    <hr>
    <h2>HelloVuex</h2>
    <hello-vuex></hello-vuex>
  </div>
</template>

<script>
import HelloVuex from './components/HelloVuex';

export default {
  name: 'App'.data() {
    return {
      message: 'I'm an App component'}},components: {
    HelloVuex
  },
  methods: {
    addition() {
      // Call increment
      this.$store.commit('increment');
    },
    substraction() {
      // Call decrement
      this.$store.commit('decrement'); }}}</script>

<style>
</style>

Copy the code

HelloVuex

<! -- -->
<template>
  <div>
      {{ this.$store.state.counter }}
  </div>
</template>

<script>
export default {
  data () {
    return{}; }}</script>
<style lang='stylus' scoped>
</style>
Copy the code

Vuex core concepts

State

Single state tree (single data source)

Create only one store object

Getters (similar to calculating properties)

The basic use

getters: {
    powerCounter(state) {
        returnstate.counter * state.counter; }}Copy the code
{{ $store.getters.powerCounter }}
Copy the code

Getters as the argument

getters: {
    powerCounter(state) {
            return state.counter * state.counter;
        },
        more20Stu(state) {
            return state.students.filter(s= > s.age >= 20);
        },
        more20StuLength(state, getters) {
            return getters.more20Stu.length;
        },
        // Return a function directly
        moreAgeStu(state) {
            return function(age) {
                return state.students.filter(s= >s.age >= age).length; }}}Copy the code

Mutations- Status update

  • The only way to update the store state of Vuex is to commit Mutation
  • Mutation mainly includes two parts:
    • Event type of string (type)
    • A callback function (handler) whose first argument is state

With parameters

// Change the state method of the share
mutations: {
    // The default parameter is state
    increment(state) {
        state.counter++;
    },
    decrement(state) {
        state.counter--;
    },
    // Carry parameters
    incrementCount(state, count){ state.counter += count; }},Copy the code
addCount(count) {
    this.$store.commit('incrementCount', count)
}
Copy the code

Submit style

this.$store.commit({
    type: 'incrementCount'.count: 5
})
Copy the code
incrementCount(state, payLoad) {
    state.counter += payLoad.count;
}
Copy the code

Response principle of Vuex data

  • The state in Vuex’s store is responsive, and the Vue component updates automatically when the data in the state changes

    • Requires that data in state be initialized. If it is not initialized, it will not be reactive

    • info: {
          name: 'aaa'.age: 40.height: 1.98
      }
      Copy the code
    • updateInfo(state) {
          // state.info.name = 'bbb'; / / response type
          state.info['address'] = 'chengdu'; // Non-responsive, no initialization
      }
      Copy the code
  • The solution

    Vue.set(state.info, 'address', 'chengdu');
    Copy the code
  • Deleting object Properties

    delete state.info.age; // Not reactive
    Vue.delete(state.info, 'age'); / / response type
    Copy the code

Actions – asynchronous

Change state asynchronously in Actions, not mutations

actions: {
    // context: context
    aUpdateInfo(context, payLoad) {
        setTimeout(() = > {
            2. the method in // mutations
            context.commit('updateInfo');
            console.log(payLoad);
        }, 1000)}},Copy the code
updateInfo() {
    // this.$store.commit('updateInfo');
 	// Use dispatch instead of commit
    this.$store.dispatch('aUpdateInfo'.'I am content')}Copy the code

Notify external callback completion

Method 1:

actions: {
    // context: context
    aUpdateInfo(context, payLoad) {
        setTimeout(() = > {
            context.commit('updateInfo');
            console.log(payLoad);
            console.log(payLoad.message);
            payLoad.success();
        }, 1000); }}Copy the code
updateInfo() {
    // this.$store.commit('updateInfo');
    this.$store.dispatch('aUpdateInfo', {
        message: 'I am the message I carry'.success: () = > {
            console.log('The inside is done.')}}}Copy the code

The Elegant Way 2:

aUpdateInfo(context, payLoad) {
    return new Promise((resolve, reject) = > {
        setTimeout(() = > {
            context.commit('updateInfo');
            console.log(payLoad);
            // console.log(payLoad.message);
            // payLoad.success();
            resolve('success');
        }, 1000); })}Copy the code
updateInfo() {
    // this.$store.commit('updateInfo');
    // this.$store.dispatch('aUpdateInfo', {
    // message: 'I am carrying a message ',
    // success: () => {
    // console.log(' inside is done ')
    / /}
    // })
    this.$store.dispatch('aUpdateInfo'.'I am the message I carry')
        .then((res) = > {
        console.log('outside'+ res); })}Copy the code

Modules

Only one store can be created from a single state tree. Modules can create different modules, and stores can be created from different modules.

const moduleA = {
    state: {
        name: 'zhangsan'
    },
    mutations: {
        updateName(state, payLoad){ state.name = payLoad; }},actions: {
        aUpdateNameA(context) {
            setTimeout(() = > {
                context.commit('updateName'.'wangwu')},1000); }},getters: {
        fullname(state) {
            return state.name + '1111';
        },
        fullname2(state, getters) {
            return getters.fullname + '222';
        },
        fullname3(state, getters, rootstate) {
            returngetters.fullname2 + rootstate.counter; }}}const moduleB = {
    state: {
        name: 'lisi'
    },
    mutations: {},actions: {},getters: {}}Copy the code
modules: {
    a: moduleA,
    b: moduleB
}
Copy the code
<h2>{{ $store.state.a.name }}</h2>
<h2>{{ $store.state.b.name }}</h2>
<h2>{{ $store.getters.fullname }}</h2>
<h2>{{ $store.getters.fullname2 }}</h2>
<h2>{{ $store.getters.fullname3 }}</h2>

<button @click="updateName">Modify the name</button>
<button @click="aUpdateNameA">Changing names asynchronously</button>
Copy the code
updateName() {
    this.$store.commit('updateName'.'fawaikuangtu');
},
aUpdateNameA() {
    this.$store.dispatch('aUpdateNameA');
}
Copy the code

The project structure

Extract the file in index.js into the corresponding module, and then import the corresponding module in index.js

├─ index.html ├─ download.js ├─ API │ ├─ ├─ ├─Extract THE API request├ ─ ─ components │ ├ ─ ─ App. Vue │ └ ─ ─... └ ─ ─ store ├ ─ ─ index. Js# where we assemble modules and export store├ ─ ─ actions. JsRoot level action├ ─ ─ mutations. JsMutation at the root level└ ─ ─ modules ├ ─ ─ cart. Js# Shopping cart module└ ─ ─ products. Js# Product module
Copy the code