Vue2 (state management Vuex)

1. State management Vuex

Vuex is a state management pattern 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.

在这里插入图片描述

The core of Vuex: state, mutations, actions

state:存储公共的一些数据
mutations:定义一些方法来修改state中的数据,数据怎么改变
actions: 使用异步的方式来触发mutations中的方法进行提交。
The code in this part we use in vue-cli

Two, the state state

声明

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

Vue.use(Vuex)

export default new Vuex.Store({
    
    
  state: {
    
    
    count:11
  },
  mutations: {
    
    

  },
  actions: {
    
    

  }
})

使用

// 直接在模板中使用
<template>
  <div>
     vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
  </div>
</template>
// 在方法中使用
ceshi(){
    
    
  console.log("Vuex中的状态数据count:",this.$store.state.count);
    this.$router.push({
    
    
      path:"/ceshi"
    },()=>{
    
    },()=>{
    
    })
  }

在这里插入图片描述

在计算属性中使用

When a component needs to get multiple states, declaring these states as computed properties is a bit repetitive and redundant. To solve this problem, we can use the mapState helper function to help us generate computed properties, saving you from pressing a few keys.

// 在组件中导入mapState函数。mapState函数返回的是一个对象
import {
    
    mapState} from 'vuex'
// 在组件中导入mapState函数。mapState函数返回的是一个对象
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <el-button @click="gouwucheclick">购物车</el-button>
      <el-button @click="ceshi">测试</el-button>
      <br>
      vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
      <br>{
    
    {
    
     count }}
      <br> doubleCount:{
    
    {
    
     doubleCount }}
    </div>
    <router-view/>
  </div>
</template>

<script>
import {
    
    mapState} from 'vuex'
  export default{
    
    
    data(){
    
    
      return{
    
    
        baseCount:10
      }
    },
    methods:{
    
    
      gouwucheclick(){
    
    
        this.$router.push({
    
    
          path:"/gouwuche"
        },()=>{
    
    },()=>{
    
    })
      },
      ceshi(){
    
    
        
        console.log("Vuex中的状态数据count:",this.$store.state.count);
        this.$router.push({
    
    
          path:"/ceshi"
        },()=>{
    
    },()=>{
    
    })
      }
    },
    computed:mapState({
    
    
      count:'count',
      doubleCount(state){
    
    
        return state.count * 2 + this.baseCount
      } 
    })
  }
</script>

在这里插入图片描述
使用展开运算符

In the previous example, it was not convenient to mix with local computed properties. Below we use the spread operator so that it can be used with local computed properties.

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <el-button @click="gouwucheclick">购物车</el-button>
      <el-button @click="ceshi">测试</el-button>
      <br>本地的计算属性{
    
    {
    
     localCount }}
      <br>
      vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
      <br>{
    
    {
    
     count }}
      <br> doubleCount:{
    
    {
    
     doubleCount }}
    </div>
    <router-view/>
  </div>
</template>

<script>
import {
    
    mapState} from 'vuex'
  export default{
    
    
    data(){
    
    
      return{
    
    
        baseCount:10
      }
    },
    methods:{
    
    
      gouwucheclick(){
    
    
        this.$router.push({
    
    
          path:"/gouwuche"
        },()=>{
    
    },()=>{
    
    })
      },
      ceshi(){
    
    
        this.baseCount=5 
        console.log("Vuex中的状态数据count:",this.$store.state.count);
        this.$router.push({
    
    
          path:"/ceshi"
        },()=>{
    
    },()=>{
    
    })
      }
    },
    computed:{
    
    
      localCount(){
    
    
        // 本地的计算属性,没有vuex中的状态参与
        return this.baseCount + 1
      },
      ...mapState({
    
    
        count:'count',
        doubleCount(state){
    
    
          return state.count * 2 + this.baseCount
        }
      })
    }
  }
</script>

在这里插入图片描述

Three, mutations

The data in the state is read-only and cannot be modified directly. The only way to modify the data in the state is to call the mutation method.
Use the commit() function to call the mutation function.

注意:mutation中只能执行同步方法。

  mutations: {
    
    
    // 在mutations中定义方法,在方法中修改state
    // state是状态,num是额外的参数
   add(state,num){
    
    
     state.count = state.count +num
   }
 },

直接调用

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <el-button @click="gouwucheclick">购物车</el-button>
      <el-button @click="ceshi">测试</el-button>
      <el-button @click="addcount">调用add</el-button>
      <br>本地的计算属性{
    
    {
    
     localCount }}
      <br>
      vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
      <br>{
    
    {
    
     count }}
      <br> doubleCount:{
    
    {
    
     doubleCount }}
    </div>
    <router-view/>
  </div>
</template>

<script>
import {
    
    mapState} from 'vuex'
  export default{
    
    
    data(){
    
    
      return{
    
    
        baseCount:10
      }
    },
    methods:{
    
    
      gouwucheclick(){
    
    
        this.$router.push({
    
    
          path:"/gouwuche"
        },()=>{
    
    },()=>{
    
    })
      },
      ceshi(){
    
    
        this.baseCount=5 
        console.log("Vuex中的状态数据count:",this.$store.state.count);
        this.$router.push({
    
    
          path:"/ceshi"
        },()=>{
    
    },()=>{
    
    })
      },
      addcount(){
    
    
        this.$store.commit('add',1)
      }
    },
    computed:{
    
    
      localCount(){
    
    
        // 本地的计算属性,没有vuex中的状态参与
        return this.baseCount + 1
      },
      ...mapState({
    
    
        count:'count',
        doubleCount(state){
    
    
          return state.count * 2 + this.baseCount
        }
      })
    }
  }
</script>

Demo 2

使用辅助函数(mapMutations)简化

import {
    
    mapMutations} from 'vuex'

Four, actions

The method executed in actions can be asynchronous.
To modify the content in state in actions, mutation is required.
Calling an action in a component requires calling the dispatch() function.

Proceed as follows:
声明action方法

actions: {
    
    
    delayAdd(countext,num){
    
    
      // 在action中调用mutation中的方法
      setTimeout(()=>{
    
    
        countext.commit('add',num)
      },2000)
    }
  },

直接调用action方法

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <el-button @click="gouwucheclick">购物车</el-button>
      <el-button @click="ceshi">测试</el-button>
      <el-button @click="addcount">调用add</el-button>
      <el-button @click="addcountAction">调用actions中的方法</el-button>
      <br>本地的计算属性{
    
    {
    
     localCount }}
      <br>
      vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
      <br>{
    
    {
    
     count }}
      <br> doubleCount:{
    
    {
    
     doubleCount }}
    </div>
    <router-view/>
  </div>
</template>

<script>
import {
    
    mapState} from 'vuex'
  export default{
    
    
    data(){
    
    
      return{
    
    
        baseCount:10
      }
    },
    methods:{
    
    
      gouwucheclick(){
    
    
        this.$router.push({
    
    
          path:"/gouwuche"
        },()=>{
    
    },()=>{
    
    })
      },
      ceshi(){
    
    
        this.baseCount=5 
        console.log("Vuex中的状态数据count:",this.$store.state.count);
        this.$router.push({
    
    
          path:"/ceshi"
        },()=>{
    
    },()=>{
    
    })
      },
      addcount(){
    
    
        this.$store.commit('add',1)
      },
      addcountAction(){
    
    
        this.$store.dispatch('delayAdd',2)
      }
    },
    computed:{
    
    
      localCount(){
    
    
        // 本地的计算属性,没有vuex中的状态参与
        return this.baseCount + 1
      },
      ...mapState({
    
    
        count:'count',
        doubleCount(state){
    
    
          return state.count * 2 + this.baseCount
        }
      })
    }
  }
</script>

Five, modules

In a complex project, we cannot accumulate a large amount of data in the store, so the content of the store will be too much, and it will be messy and inconvenient to manage. So there is a module. He cut the original store into modules one by one. Each module has its own store, mutation, actions and getters

store中定义一个module

const storeModuleA={
    
    
    state:{
    
    
        countA:10
    },
    mutations:{
    
    
        addA(state){
    
    
            state.countA++
            console.log("moduleA:"+state.countA);
        },
        //  此方法和root中的方法名字一致 
        add(state){
    
    
            console.log("moduleA:"+state.countA);
        }
    }
}

export default storeModuleA

在store.js中,导入并注册此module

import Vue from 'vue'
import Vuex from 'vuex'
import storeModuleA from './stroeModuleA'

Vue.use(Vuex)

export default new Vuex.Store({
    
    
  state: {
    
    
    count:11,
  },
  mutations: {
    
    
    // state是状态,num是额外的参数
    add(state,num){
    
    
      console.log('root中的add');
      state.count = state.count +num
    }
  },
  actions: {
    
    
    delayAdd(countext,num){
    
    
      // 在action中调用mutation中的方法
      setTimeout(()=>{
    
    
        countext.commit('add',num)
      },2000)
    }
  },
  modules: {
    
    
    a:storeModuleA
  }
})

在组件中使用子模块中的状态

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <el-button @click="gouwucheclick">购物车</el-button>
      <el-button @click="ceshi">测试</el-button>
      <el-button @click="addcount">调用add</el-button>
      <el-button @click="addcountAction">调用actions中的方法</el-button>
      <br>本地的计算属性{
    
    {
    
     localCount }}
      <br>
      vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
      <br>{
    
    {
    
     count }}
      <br> doubleCount:{
    
    {
    
     doubleCount }}

      <hr>
      {
    
    {
    
     $store.state.a.countA }}
      <el-button @click="addMoudleAaddA">调用a模块中的mutation-addA</el-button>
    </div>
    <router-view/>
  </div>
</template>

<script>
import {
    
    mapState} from 'vuex'
  export default{
    
    
    data(){
    
    
      return{
    
    
        baseCount:10
      }
    },
    methods:{
    
    
      gouwucheclick(){
    
    
        this.$router.push({
    
    
          path:"/gouwuche"
        },()=>{
    
    },()=>{
    
    })
      },
      ceshi(){
    
    
        this.baseCount=5 
        console.log("Vuex中的状态数据count:",this.$store.state.count);
        this.$router.push({
    
    
          path:"/ceshi"
        },()=>{
    
    },()=>{
    
    })
      },
      addcount(){
    
    
        this.$store.commit('add',1)
      },
      addcountAction(){
    
    
        this.$store.dispatch('delayAdd',2)
      },
      addMoudleAaddA(){
    
    
        this.$store.commit('addA')
      },
    },
    computed:{
    
    
      localCount(){
    
    
        // 本地的计算属性,没有vuex中的状态参与
        return this.baseCount + 1
      },
      ...mapState({
    
    
        count:'count',
        doubleCount(state){
    
    
          return state.count * 2 + this.baseCount
        }
      })
    }
  }
</script>

Example 4


在store.js中,导入并注册此module

在组件中使用子模块中的状态

没有声明namespace的情况
子模块中的mutation在没有使用namespace的情况下,这些方法会注册到root中。
如果子模块中的mutation和root中的一样。则都会被调用。

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <el-button @click="gouwucheclick">购物车</el-button>
      <el-button @click="ceshi">测试</el-button>
      <el-button @click="addcount">调用add</el-button>
      <el-button @click="addcountAction">调用actions中的方法</el-button>
      <br>本地的计算属性{
    
    {
    
     localCount }}
      <br>
      vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
      <br>{
    
    {
    
     count }}
      <br> doubleCount:{
    
    {
    
     doubleCount }}

      <hr>
      {
    
    {
    
     $store.state.a.countA }}
      <el-button @click="addMoudleAaddA">调用a模块中的mutation-addA</el-button>
      <el-button @click="addMoudleAadd">调用a模块中的mutation-add</el-button>
    </div>
    <router-view/>
  </div>
</template>

<script>
import {
    
    mapState} from 'vuex'
  export default{
    
    
    data(){
    
    
      return{
    
    
        baseCount:10
      }
    },
    methods:{
    
    
      gouwucheclick(){
    
    
        this.$router.push({
    
    
          path:"/gouwuche"
        },()=>{
    
    },()=>{
    
    })
      },
      ceshi(){
    
    
        this.baseCount=5 
        console.log("Vuex中的状态数据count:",this.$store.state.count);
        this.$router.push({
    
    
          path:"/ceshi"
        },()=>{
    
    },()=>{
    
    })
      },
      addcount(){
    
    
        this.$store.commit('add',1)
      },
      addcountAction(){
    
    
        this.$store.dispatch('delayAdd',2)
      },
      addMoudleAaddA(){
    
    
        this.$store.commit('addA')
      },
      addMoudleAadd(){
    
    
        this.$store.commit('add')
      }
    },
    computed:{
    
    
      localCount(){
    
    
        // 本地的计算属性,没有vuex中的状态参与
        return this.baseCount + 1
      },
      ...mapState({
    
    
        count:'count',
        doubleCount(state){
    
    
          return state.count * 2 + this.baseCount
        }
      })
    }
  }
</script>

在这里插入图片描述
声明namespace的情况
在module中添加

import Vue from 'vue'
import Vuex from 'vuex'
import storeModuleA from './stroeModuleA'

Vue.use(Vuex)

export default new Vuex.Store({
    
    
  state: {
    
    
    count:11,
  },
  mutations: {
    
    
    // state是状态,num是额外的参数
    add(state,num){
    
    
      console.log('root中的add');
      state.count = state.count +num
    }
  },
  actions: {
    
    
    delayAdd(countext,num){
    
    
      // 在action中调用mutation中的方法
      setTimeout(()=>{
    
    
        countext.commit('add',num)
      },2000)
    }
  },
  modules: {
    
    
    a:{
    
    
      namespaced:true,
      ...storeModuleA
    }
  }
})

在组件中调用,加上别名即可

this.$store.commit('a/addA');
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <el-button @click="gouwucheclick">购物车</el-button>
      <el-button @click="ceshi">测试</el-button>
      <el-button @click="addcount">调用add</el-button>
      <el-button @click="addcountAction">调用actions中的方法</el-button>
      <br>本地的计算属性{
    
    {
    
     localCount }}
      <br>
      vuex中的状态数据count:{
    
    {
    
     $store.state.count }}
      <br>{
    
    {
    
     count }}
      <br> doubleCount:{
    
    {
    
     doubleCount }}

      <hr>
      {
    
    {
    
     $store.state.a.countA }}
      <el-button @click="addMoudleAaddA">调用a模块中的mutation-addA</el-button>
      <el-button @click="addMoudleAadd">调用a模块中的mutation-add</el-button>
    </div>
    <router-view/>
  </div>
</template>

<script>
import {
    
    mapState} from 'vuex'
  export default{
    
    
    data(){
    
    
      return{
    
    
        baseCount:10
      }
    },
    methods:{
    
    
      gouwucheclick(){
    
    
        this.$router.push({
    
    
          path:"/gouwuche"
        },()=>{
    
    },()=>{
    
    })
      },
      ceshi(){
    
    
        this.baseCount=5 
        console.log("Vuex中的状态数据count:",this.$store.state.count);
        this.$router.push({
    
    
          path:"/ceshi"
        },()=>{
    
    },()=>{
    
    })
      },
      addcount(){
    
    
        this.$store.commit('add',1)
      },
      addcountAction(){
    
    
        this.$store.dispatch('delayAdd',2)
      },
      addMoudleAaddA(){
    
    
        this.$store.commit('addA')
      },
      addMoudleAadd(){
    
    
        this.$store.commit('a/add')
      }
    },
    computed:{
    
    
      localCount(){
    
    
        // 本地的计算属性,没有vuex中的状态参与
        return this.baseCount + 1
      },
      ...mapState({
    
    
        count:'count',
        doubleCount(state){
    
    
          return state.count * 2 + this.baseCount
        }
      })
    }
  }
</script>

在这里插入图片描述

最后

送大家一句话:不是井里没有水,而是挖的不够深

Guess you like

Origin blog.csdn.net/H20031011/article/details/132532388