Vue-Vuex(3.x)

前言

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库

官网介绍:https://vuex.vuejs.org/zh/

以下主要讲解的是如何定义与使用,如果还没有对vuex进行了解的话,请先查看官网,了解其功能、用法及用途。

关于vuex,在之前:https://blog.youkuaiyun.com/qq_57404736/article/details/124471345的第十章,讲解vue的时候,讲过。本章将详细讲解vuex的使用

安装

如果你有一个测试项目,则可以不看使用章节->基本准备->第一章重新创建测试项目,使用如下命令,在你的测试项目安装vuex依赖即可

1、安装依赖包

npm install vuex --save

# 或

cnpm install vuex --save

2、创建基本文件

src目录下,创建store目录,然后在里面创建index.js文件用于引入vuex

在这里插入图片描述

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {},
});

3、导入vuex

main.js中导入刚刚创建好的store下index文件,并挂在到Vue示例上

import Vue from "vue";
import App from "./App.vue";
import store from "./store"; // 导入store下index.js暴露的的Store

Vue.config.productionTip = false;

new Vue({
  store, // 挂在到vue实例上
  render: (h) => h(App),
}).$mount("#app");

使用

以下进行举例使用讲解

使用两个组件,对同一个值(count)进行加减操作

State、Getter、Mutations、Action在页面中使用皆有两种使用方式,请认真观看

0、基本准备

0.1、使用脚手架创建项目

  1. 使用vue ui的命令,创建一个包含vuex组件的基本vue项目。如果不知道vue ui怎么使用的话,可以查看:https://blog.youkuaiyun.com/qq_57404736/article/details/124471345第八章节,下载vue-cli脚手架

  2. 创建的时候选择手动版本,手动导入需要的功能

    在这里插入图片描述

  3. 然后选择vuex,点击右侧按钮打开

    在这里插入图片描述

  4. 然后选择基本配置后,创建项目

    在这里插入图片描述

  5. 等待项目创建完成

0.2、编写基本代码

我们演示的是两个组件实现对count进行加减的计数器功能。这样两个组件就会共享数据count,并对其值进行操作

  1. 先清空components目录下所有案例组件,然后新建addtation、subtraction两个组件,分别针对count进行加减操作

    在这里插入图片描述

    • addtation

      <template>
        <div>
          <h2>当前count值:</h2>
          <button>+1</button>
        </div>
      </template>
      
      <script>
        export default {
          methods:{
            
          }
        }
      </script>
      
    • subtraction

      <template>
        <div>
          <h2>当前count值:</h2>
          <button>-1</button>
        </div>
      </template>
      
      <script>
        export default {
          methods:{
            
          }
        }
      </script>
      
  2. 然后在App.vue页面里引入这两个组件,进行展示

    <template>
      <div id="app">
        <addition></addition>
        <subtraction></subtraction>
      </div>
    </template>
    <script>
    import addition from "./components/addition.vue";
    import subtraction from "./components/subtraction.vue";
    
    export default {
      name: "App",
      components: {
        addition,
        subtraction,
      },
    };
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
  3. 准备完毕后,启动项目,查看页面是否正常显示

    在这里插入图片描述

1、State

State和组件中的data属性功能基本相同,区别是,State中定义的变量称为状态,且所有组件都可访问到

存储在 Vuex 中的数据和 Vue 实例中的 data 遵循相同的规则,例如状态对象必须是纯粹 (plain) 的。

1.1、定义

  1. 在左侧store目录中,存放的为vuex中所有的内容,打开index.js文件,里面可以定义所有使用到的变量及方法

    在这里插入图片描述

  2. 其中,state,即是要共享的变量存放的位置。

  3. 我们在state对象内,定义变量count,默认值为0

    import Vue from "vue";
    import Vuex from "vuex";
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {
        count:0
      },
      getters: {},
      mutations: {},
      actions: {},
      modules: {},
    });
    

1.2、使用方法一(直接)

Vuex 通过 Vue 的插件系统将 store 实例从根组件中“注入”到所有的子组件里。且子组件能通过 this.$store 访问到。

我们在addition组件内,使用方法一引入,使其正常显示值。

语法

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

使用

<template>
  <div>
      <!-- 在dom中使用js,this可以省略 -->
    <h2>当前count值:{{$store.state.count}}</h2>
    <button>+1</button>
  </div>
</template>

<script>
  export default {
    data(){
      return {

      }
    },
    methods:{

    }
  }
</script>

结果

在这里插入图片描述

1.3、使用方法二(引入)

vuex中提供了mapState函数,参数为数组,数组中的内容即为需要导出的变量

我们在subtraction组件内,使用方法二引入,使其正常显示值。

语法

// 1. 从vuex中按需导入 mapState 函数
import { mapState } from 'vuex'
// 2. 将全局数据,映射为当前组件的计算属性
computed: {
    ...mapState(['count'])
}

使用

<template>
  <div>
    <h2>当前count值:{{count}}</h2>
    <button>-1</button>
  </div>
</template>

<script>
  import { mapState } from 'vuex';
  export default {
    computed:{
      ...mapState(['count'])
    },
  }
</script>

结果

在这里插入图片描述

2、Getter

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)

假设我们这个count代表的为年龄,不能为0(后面我们定义方法的时候,会有个-1操作,我们需要对这个值进行判断)

其他办法

我们可以在使用的组件中定义计算属性,进行过滤操作。但是如果使用的组件多的话,则需要每个组件都引入相同的计算属性,十分没必要

代码

<template>
  <div>
    <h2>当前count值:{{count}}</h2>
    <h2>当前sex值:{{sex}}</h2>
    <button>-1</button>
  </div>
</template>

<script>
  import { mapState } from 'vuex';
  export default {
    computed:{
      ...mapState(['count']),
      sex:function(){ // 定义sex属性
        if(this.$store.state.count < 1){
          return 1 // 如果state中的count值小于1,则返回1
        }
        return this.$store.state.count
      }
    },
    methods:{
      
    }
  }
</script>

结果

在这里插入图片描述

1.1、定义

  1. store目录下的index.js中的getters中,定义我们需要针对state中的变量,进行计算的属性

  2. 如果count小于1,则默认为1,并返回一个名为sex的变量

    import Vue from "vue";
    import Vuex from "vuex";
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {
        count:0
      },
      getters: {
        sex(state){
          if(state.count < 1){
            return 1
          }
          return state.count
        }
      },
      mutations: {},
      actions: {},
      modules: {},
    });
    

1.2、使用方法一(直接)

语法

this.$store.getters.变量名称

使用

<template>
  <div>
    <h2>当前count值:{{$store.state.count}}</h2>
      <!-- Getter属性 -->
    <h2>当前sex值:{{$store.getters.sex}}</h2>
    <button>+1</button>
  </div>
</template>

结果

在这里插入图片描述

1.3、使用方法二(引入)

语法

// 1. 从vuex中按需导入 mapGetters 函数
import { mapGetters } from 'vuex'
// 2. 将Getter里面的属性,映射为当前组件的计算属性
computed: {
    ...mapGetters(['sex'])
}

使用

<template>
  <div>
    <h2>当前count值:{{ count }}</h2>
    <h2>当前sex值:{{ sex }}</h2>
    <button>-1</button>
  </div>
</template>

<script>
  import { mapState,mapGetters } from 'vuex';
  export default {
    computed:{
      ...mapState(['count']),
      ...mapGetters(['sex'])
    },
  }
</script>

结果

在这里插入图片描述

3、Mutations

想要修改状态(count)的值,虽然在使用上,通过this.$store.state.count++修改值,并不会不会报错,并且可以修改成功。

但是,官方并不建议直接修改值,而是在Mutations中定义修改状态的方法,然后执行this.$store.commit('方法名'),调用方法修改状态的值。

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation

1.1、定义

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count:0
  },
  getters: {},
  mutations: {
    // 无参
    addCount(state){
      state.count++;
    },
      
    // 有参
    addCountNum(state,num){
      state.count += num;
    },
      
    // 无参
    subCount(state){
      state.count--;
    },
      
    // 有参
    subCountNum(state,num){
      state.count -= num;
    }
  },
  actions: {},
  modules: {},
});

1.2、使用方法一(直接)

(1)、无参

语法

this.$store.commit('方法名');

使用

<template>
  <div>
    <h2>当前count值:{{$store.state.count}}</h2>
    <button @click="addition">+1</button>
  </div>
</template>

<script>
  export default {
    methods:{
      addition(){
        this.$store.commit('addCount');
      }
    }
  }
</script>

结果

在这里插入图片描述

(2)、有参

指定每次点击后,count值添加5

语法

this.$store.commit('方法名','参数1','参数2',...)

使用

<template>
  <div>
    <h2>当前count值:{{$store.state.count}}</h2>
    <button @click="addition">+1</button>
    <button @click="additionNum">+5</button>
  </div>
</template>

<script>
  export default {
    methods:{
      addition(){
        this.$store.commit('addCount');
      },
      additionNum(){
        this.$store.commit('addCountNum',5);
      }
    }
  }
</script>

结果

在这里插入图片描述

1.3、使用方法二(引入)

语法

<button @click="subCount">-1</button>
<button @click="subCountNum(5)">-5</button>

<script>
    // 1. 从vuex中按需导入 mapMutations 函数
    import { mapMutations } from 'vuex'
    // 2. 将Mutations中的方法,映射为当前组件的方法
    methods: {
        ...mapMutations(['subCount','subCountNum'])
    }
</script>    

使用

<template>
  <div>
    <h2>当前count值:{{ count }}</h2>
    <button @click="subCount">-1</button>
    <button @click="subCountNum(5)">-5</button>
  </div>
</template>

<script>
  import { mapState,mapGetters,mapMutations } from 'vuex';
  export default {
    computed:{
      ...mapState(['count']),
    },
    methods:{
      ...mapMutations(['subCount','subCountNum'])
    }
  }
</script>

结果

在这里插入图片描述

1.4、注意

mutation 必须是同步函数,如果你要使用异步函数,则在后面章节的Action中可以看到使用方法。

虽然在mutation中执行异步函数,依旧会修改状态的值,但是在devtools中不能很好的观察到属性正确的值,非常不建议!!!

devtools工具我们会在第七章讲解到。

在这里插入图片描述

在这里插入图片描述

4、Mytations-type

使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。这样可以使 linter 之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然。

我们可以使用 ES2015 风格的计算属性命名功能,来使用一个常量作为函数名

4.1、编写mutation-type.js文件

store目录下,新建mutation-type.js文件,定义是所有的方法名称

export default {
  ADD_COUNT: 'addCount',
  ADD_COUNT_NUM: 'addCountNum',
  SUB_COUNT: 'subCount',
  SUB_COUNT_NUM: 'subCountNum',
  /// ...
}

4.2、引入使用

store->index.js文件里面引入mutation-type.js文件,并在定义方法的时候使用。

import Vue from "vue";
import Vuex from "vuex";
import MUTATION_TYPE from "./mutation-type";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count:0
  },
  getters: {},
  mutations: {
    [MUTATION_TYPE.ADD_COUNT](state){
      state.count++;
    },
    [MUTATION_TYPE.ADD_COUNT_NUM](state,num){
      state.count += num;
    },
    [MUTATION_TYPE.SUB_COUNT](state){
      state.count--;
    },
    [MUTATION_TYPE.SUB_COUNT_NUM](state,num){
      state.count -= num;
    }
  },
  actions: {},
  modules: {},
});

5、Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

异步修改状态的步骤:定义state -> 在mutations中编写方法修改state -> 在actions中编写异步方法调用mutations中的方法

1.1、定义

import Vue from "vue";
import Vuex from "vuex";
import MUTATION_TYPE from "./mutation-type";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count:0
  },
  getters: {},
  mutations: {
    [MUTATION_TYPE.ADD_COUNT](state){
      state.count++;
    },
    [MUTATION_TYPE.ADD_COUNT_NUM](state,num){
      state.count += num;
    },
    [MUTATION_TYPE.SUB_COUNT](state){
      state.count--;
    },
    [MUTATION_TYPE.SUB_COUNT_NUM](state,num){
      state.count -= num;
    },
  },
  actions: {
    delayedAddCount(context){
      // 异步方法
      setTimeout(() => {
        context.commit(MUTATION_TYPE.ADD_COUNT);
      }, 1000);
    },
    delayedSubCount(context){
      // 异步方法
      setTimeout(() => {
        context.commit(MUTATION_TYPE.SUB_COUNT);
      }, 1000);
    }
  },
  modules: {},
});

1.2、使用方法一(直接)

有参使用方法和Mutations中的有参方法使用一致,直接在dispatch参数后面添加其他方法参数即可

语法

this.$store.dispatch('方法名',参数1,参数2,...)

使用

<template>
  <div>
    <h2>当前count值:{{$store.state.count}}</h2>
    <button @click="addition">+1</button>
    <button @click="additionNum">+5</button>
    <button @click="delayedAddCount">延迟+1</button>
  </div>
</template>

<script>
  export default {
    methods:{
      addition(){
        this.$store.commit('addCount');
      },
      additionNum(){
        this.$store.commit('addCountNum',5);
      },
      delayedAddCount(){
        this.$store.dispatch('delayedAddCount')
      }
    }
  }
</script>

结果

在这里插入图片描述

1.3、使用方法二(引入)

语法

<button @click="subCount">-1</button>
<button @click="subCountNum(5)">-5</button>

<script>
    // 1. 从vuex中按需导入 mapActions 函数
    import { mapActions } from 'vuex'
    // 2. 将Actions中的方法,映射为当前组件的方法
    methods: {
        ...mapActions(['subCount','subCountNum'])
    }
</script>

使用

<template>
  <div>
    <h2>当前count值:{{ count }}</h2>
    <button @click="subCount">-1</button>
    <button @click="subCountNum(5)">-5</button>
    <button @click="delayedSubCount">延迟-1</button>
  </div>
</template>

<script>
  import { mapState,mapGetters,mapMutations,mapActions } from 'vuex';
  export default {
    computed:{
      ...mapState(['count']),
    },
    methods:{
      ...mapMutations(['subCount','subCountNum']),
      ...mapActions(['delayedSubCount'])
    }
  }
</script>

结果

在这里插入图片描述

6、Module

6.1、中型项目

当我们的项目为中型项目,并且用到vuex比较多的时候,我们就一般不会把state、getter、mutation、action都定义在一个js文件里,不然会导致js文件臃肿。

一般会采用模块化方法,分别把这几个提取到单独自己的js文件里面,然后在index.js中分别引入使用即可

store目录中,分别创建state.js、getters.js、mutations.js、actions.js,然后在index.js中引用即可

目录结构

在这里插入图片描述

state.js
export default {
  count:0
}
getter.js
export default {
  sex(state){
    if(state.count < 1){
      return 1
    }
    return state.count
  }
}
mutation.js
import MUTATION_TYPE from "./mutation-type";

export default {
  [MUTATION_TYPE.ADD_COUNT](state){
    state.count++;
  },
  [MUTATION_TYPE.ADD_COUNT_NUM](state,num){
    state.count += num;
  },
  [MUTATION_TYPE.SUB_COUNT](state){
    state.count--;
  },
  [MUTATION_TYPE.SUB_COUNT_NUM](state,num){
    state.count -= num;
  },
}
action.js
import MUTATION_TYPE from "./mutation-type";

export default {
  delayedAddCount(context){
    // 异步方法
    setTimeout(() => {
      context.commit(MUTATION_TYPE.ADD_COUNT);
    }, 1000);
  },
  delayedSubCount(context){
    // 异步方法
    setTimeout(() => {
      context.commit(MUTATION_TYPE.SUB_COUNT);
    }, 1000);
  }
}
index.js
import Vue from "vue";
import Vuex from "vuex";
import state from "./state"
import getters from "./getters"
import mutations from "./mutations"
import actions from "./actions"

Vue.use(Vuex);

export default new Vuex.Store({
  state,
  getters,
  mutations,
  actions,
  // modules,
});

6.2、大型项目(Module)

当我们的项目很大,模块很多的时候,这样好像也并不是特别好,代码也很臃肿,所以,vuex给我们提供了Module功能,按照模块进行分类存放。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

定义
  • 可以在主index.js下的modules中编写

    在这里插入图片描述

  • 也可以单独创建文件夹,拥有自己单独的index.js、state.js、getters.js、mutations.js、actions.js文件

    在这里插入图片描述

  • user/index.js文件

    在这里插入图片描述

  • state.js文件

    在这里插入图片描述

  • 其他文件就省略不写了,类似state.js文件

  • 然后在外层index.js引入即可

    在这里插入图片描述

使用

state使用

语法

// 要在原来的state后面加上在modules中定义的变量名,然后后面.state中定义的变量
this.$store.state.user.state定义的变量名

使用

新建一个组件或者在原来的组件上直接修改代码即可

<template>
  <div>
    <h2>当前userName值:{{$store.state.user.userName}}</h2>
    <h2>当前password值:{{$store.state.user.password}}</h2>
  </div>
</template>

<script>
  export default {
    methods:{
    }
  }
</script>

结果

在这里插入图片描述

mutation使用

语法

// 和原来使用办法一致,但有问题(下一小节会讲)
this.$store.commit('方法名',参数...)

使用

<template>
  <div>
    <h2>当前userName值:{{$store.state.user.userName}}</h2>
    <h2>当前password值:{{$store.state.user.password}}</h2>
    <button @click="setUserName">点击修改姓名</button>
    <button @click="setPassword">点击修改密码</button>
  </div>
</template>

<script>
  export default {
    methods:{
      setUserName(){
        this.$store.commit('setUserName',"李四");
      },
      setPassword(){
        this.$store.commit('setPassword',"admin");
      },
    }
  }
</script>

结果

在这里插入图片描述

问题

可以看到上面使用mutation中的方法,是和原来写法一样。

那我们假如在原来主index.js中写上属于自己的相同名字的方法呢,那么会执行哪一个方法。结果是都执行,可以自行尝试。下面有解决办法!

默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的——这样使得多个模块能够对同一个 action 或 mutation 作出响应。Getter 同样也默认注册在全局命名空间,但是目前这并非出于功能上的目的(仅仅是维持现状来避免非兼容性变更)

在这里插入图片描述

命名空间

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名

启用了命名空间的 getter 和 action 会收到局部化的 getterdispatchcommit。换言之,你在使用模块内容(module assets)时不需要在同一模块内额外添加空间名前缀。更改 namespaced 属性后不需要修改模块内的代码。

语法

modules:{
    user:{
      // 开启命名空间
      namespaced: true,
      state:{
        userName:'张三',
        password:'123321'
      },
      mutations:{
        setUserName(state,name){
          state.userName = name;
        },
        setPassword(state,password){
          state.password = password;
        },
      },
    }
  },

使用

<template>
  <div>
    <h2>当前userName值:{{$store.state.user.userName}}</h2>
    <h2>当前password值:{{$store.state.user.password}}</h2>
    <button @click="setUserName">点击修改姓名</button>
    <button @click="setPassword">点击修改密码</button>
  </div>
</template>

<script>
  export default {
    methods:{
      setUserName(){
        // 地址前面加上 模块名/
        this.$store.commit('user/setUserName',"李四");
      },
      setPassword(){
        this.$store.commit('user/setPassword',"admin");
      },
    }
  }
</script>

结果

在这里插入图片描述

7、拓展

7.1、带命名空间的模块内访问全局内容

如果你希望使用全局 state 和 getter,rootStaterootGetters 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。

若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatchcommit 即可。

定义

actions:{
        setUsernameAndCount({ commit,dispatch,rootState,rootGetters },data ){
          
        },
      }

使用

页面

<template>
  <div>
    <h2>当前userName值:{{$store.state.user.userName}}</h2>
    <h2>当前password值:{{$store.state.user.password}}</h2>
    <h2>当前count值:{{$store.state.count}}</h2>
    <button @click="setUserName">点击修改姓名</button>
    <button @click="setPassword">点击修改密码</button>
    <button @click="setUsernameAndCount">点击修改姓名和Count+5</button>
  </div>
</template>

<script>
  export default {
    methods:{
      setUserName(){
        this.$store.commit('user/setUserName',"李四");
      },
      setPassword(){
        this.$store.commit('user/setPassword',"admin");
      },
      setUsernameAndCount(){
        // 传入参数为对象
        this.$store.dispatch('user/setUsernameAndCount',{name:"1234567",count:5});
      }
    }
  }
</script>

index.js

import Vue from "vue";
import Vuex from "vuex";
import state from "./state"
import getters from "./getters"
import mutations from "./mutations"
import actions from "./actions"
import MUTATION_TYPE from "./mutation-type";

Vue.use(Vuex);

export default new Vuex.Store({
  state,
  getters,
  mutations,
  actions,
  modules:{
    user:{
      namespaced: true,
      state:{
        userName:'张三',
        password:'123321'
      },
      mutations:{
        setUserName(state,name){
          state.userName = name;
        },
        setPassword(state,password){
          state.password = password;
        },
      },
      actions:{
        // 一般传入对象为参数
        setUsernameAndCount({ commit,dispatch,rootState,rootGetters },data ){
          // rootGetters 获取主模块的getters
          alert("rootGetters:" + rootGetters.sex)
          // rootState 获取主模块的state
          alert("rootState:" + rootState.count)

          // 修改自己用户名 调用自己模块的setUserName方法
          commit('setUserName',data.name) // user/setUserName

          // 调用主模块的mutations中的方法,修改主模块count
          commit(MUTATION_TYPE.ADD_COUNT_NUM,data.count,{ root: true }) // addCountNum

          // 调用主模块的actions方法,延时count+1
          // dispatch('delayedAddCount',null,{ root:true })
        },
      }
    }
  },
});

结果

在这里插入图片描述

7.2、带命名空间的模块注册全局action

若需要在带命名空间的模块注册全局 action,你可添加 root: true,并将这个 action 的定义放在函数 handler 中。

语法

someAction: {
    root: true,
    handler (namespacedContext, payload) {
    	// ... 
    } // -> 'someAction'
}

7.3、带命名空间的绑定函数

使用一:

当使用 mapStatemapGettersmapActionsmapMutations 这些函数来绑定带命名空间的模块时,写起来可能比较繁琐

<template>
  <div>
    <h2>当前userName值:{{ userName }}</h2>
    <h2>当前password值:{{ password }}</h2>
    <h2>当前count值:{{$store.state.count}}</h2>
    <button @click="setUserName">点击修改姓名</button>
    <button @click="setPassword">点击修改密码</button>
    <button @click="setUsernameAndCount">点击修改姓名和Count+5</button>
  </div>
</template>

<script>
  import { mapState,mapGetters,mapMutations,mapActions } from 'vuex';
  export default {
    computed:{
      ...mapState({
        userName: state => state.user.userName,
        password: state => state.user.password
      }),
    },
    methods:{
      ...mapMutations([
        'user/setUserName', // -> this['user/setUserName']()
        'user/setPassword', // -> this['user/setPassword']()
      ]),
      ...mapActions([
        'user/setUsernameAndCount', // -> this['user/setUsernameAndCount']()
      ]),
      setUserName(){
        this['user/setUserName']("李四");
      },
      setPassword(){
        this['user/setPassword']("admin")
      },
      setUsernameAndCount(){
        this['user/setUsernameAndCount']({name:"1234567",count:5})
      }
    }
  }
</script>
使用二:

对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文

<template>
  <div>
    <h2>当前userName值:{{ userName }}</h2>
    <h2>当前password值:{{ password }}</h2>
    <h2>当前count值:{{$store.state.count}}</h2>
    <button @click="setUserName1">点击修改姓名</button>
    <button @click="setPassword1">点击修改密码</button>
    <button @click="setUsernameAndCount1">点击修改姓名和Count+5</button>
  </div>
</template>

<script>
  import { mapState,mapGetters,mapMutations,mapActions } from 'vuex';
  export default {
    computed:{
      ...mapState("user",{
        userName: state => state.userName,
        password: state => state.password
      }),
    },
    methods:{
      ...mapMutations("user",[
        'setUserName', // -> this.setUserName()
        'setPassword', // -> this.setPassword()
      ]),
      ...mapActions("user",[
        'setUsernameAndCount', // -> this.setUsernameAndCount()
      ]),
      // 注意,自己方法不可与引用进来的方法重名!!!
      setUserName1(){
        this.setUserName("李四");
      },
      setPassword1(){
        this.setPassword("admin")
      },
      setUsernameAndCount1(){
        this.setUsernameAndCount({name:"1234567",count:5})
      }
    }
  }
</script>
使用三

你也可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数

<template>
  <div>
    <h2>当前userName值:{{ userName }}</h2>
    <h2>当前password值:{{ password }}</h2>
    <h2>当前count值:{{$store.state.count}}</h2>
    <button @click="setUserName1">点击修改姓名</button>
    <button @click="setPassword1">点击修改密码</button>
    <button @click="setUsernameAndCount1">点击修改姓名和Count+5</button>
  </div>
</template>

<script>
  // import { mapState,mapGetters,mapMutations,mapActions } from 'vuex';
  import { createNamespacedHelpers } from 'vuex'
  const { mapState, mapMutations, mapActions } = createNamespacedHelpers('user')
  export default {
    computed:{
      // 在 `some/nested/module` 中查找
      ...mapState({
        userName: state => state.userName,
        password: state => state.password
      }),
    },
    methods:{
      // 在 `some/nested/module` 中查找
      ...mapMutations([
        'setUserName', // -> this.setUserName()
        'setPassword', // -> this.setPassword()
      ]),
      ...mapActions([
        'setUsernameAndCount', // -> this.setUsernameAndCount()
      ]),
      // 注意,自己方法不可与引用进来的方法重名!!!
      setUserName1(){
        this.setUserName("李四");
      },
      setPassword1(){
        this.setPassword("admin")
      },
      setUsernameAndCount1(){
        this.setUsernameAndCount({name:"1234567",count:5})
      }
    }
  }
</script>

8、vue-devTools

vue-devtools是一款基于chrome游览器的插件,用于调试vue应用,这可以极大地提高我们的调试效率。

下载

谷歌可以通过:https://www.extfans.com/search/?q=vue,选择第一个vue.js devtools进行下载插件

使用

调试的时候,按住F12,然后就可以在浏览器开发者工具中看到

在这里插入图片描述

在这里页面里面可以组件内所有data的值,以及其他属性的值,可以进行很好的调试观察

在这里插入图片描述

在这里可以观察到vuex的值的变化

在这里插入图片描述

在这里你可以看到你执行mutation、action方法的具体时间,以及参数的变化

在这里插入图片描述

9、使用讲解

  • 小型项目(使用vuex不多的情况下),就会把所有内容都放在主模块下的index.js里面,也基本不使用mutation-type.js管理
  • 中型项目(使用vuex不多也不少的情况下),就会把index.js进行模块化管理,每个模块创建单独的js文件进行管理,可以视情况使用mutation-type.js进行管理
  • 大型项目(使用vuex很多的情况),就会使用vuex的modules进行模块管理,并且会使用mutation-type.js管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值