一、mapState

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

// store.js/*
vuex的核心管理对象模块:store*/
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)
// 状态对象
const state = { // 初始化状态 这里放置的状态可以被多个组件共享count: 1,name: 'daming'
}
const mutations = {}
const action = {}
const getters = {}export default new Vuex.Store({state, // 状态mutations, // 包含多个更新state函数的对象actions, // 包含多个队形事件回调函数的对象getters // 包含多个getter计算属性函数的对象
})
// main.js/*
入口JS*/
import Vue from 'vue'
import App from './App.vue'
import store from './store'// 创建vm
/* eslint-disable no-new */
new Vue({el: '#app',components: {App}, // 映射组件标签template: '<App/>', // 指定需要渲染到页面的模板store // 所有的组件对象都多了一个属性:$store
})

在组件中获取vuex状态
虽然将所有的状态放入Vuex,会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态,比如temp变量,tempcount,tempcount2作为组件的局部状态。

<!-- App.vue --><template><div id="example">{{count}}{{name}}{{nameAlias}}</div>
</template><script>
import { mapState } from 'vuex'   // 引入mapState
export default {data () {return {// 使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。// 如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。// 下面的temp变量,tempcount,tempcount2作为组件的局部状态temp: 'hello',tempcount: 1,tempcount2: 2}},computed: {// tempCountPlusTempCount2 这个计算属性并没有涉及到vuex管理的状态tempCountPlusTempCount2() { return this.tempcount+this.tempcount2} // 由于 Vuex 的状态存储是响应式的,所以可以使用计算属性来获得某个状态// 当状态改变时,都会重新求取计算属性,并且触发更新相关联的 DOM// 通过下面的计算属性,就可以在当前组件中访问到count,name,nameAlias等了 在模板中我们通过大括号符号打印出来// 下面的计算属性涉及到了vuex管理的状态count () { // 这实际上是ES6中对象的简化写法 完整写法是 count: function { return this.$store.state.count }return this.$store.state.age},name () { // 这实际上是ES6中对象的简化写法 完整写法是 name: function { return this.$store.state.age }return this.$store.state.age},nameAlias () {return this.$store.state.name}countplustempcount: function (state) {return this.tempcount + this.$store.state.count},countplustempcount2 (state) {return this.tempcount2 + this.$store.state.count} // 但有一个问题// 当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。比如上面的name(),count(),nameAlias(),显得重复,代码冗长// 为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:}
}
</script>

但有一个问题,当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。比如上面的name(),count(),nameAlias(),显得重复,代码冗长。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键

mapState接收一个对象
mapState函数的可以接受一个对象Object<string | function>。对象中可以包含字符串或函数。mapState()函数的返回结果是一个对象。

<template><div id="example">{{count}}{{name}}{{nameAlias}}</div>
</template><script>
import { mapState } from 'vuex'
export default {data () {return {temp: 'hello',tempcount: 1,tempcount2: 2}},computed: mapState({count: 'count',  // string    映射 this.count 为 store.state.count的值// 箭头函数可使代码更简练name: (state) => state.name, // function   映射 this.name 为 store.state.name的值nameAlias: 'name', // string   映射 this.nameAlias 为 store.state.name的值countplustempcount: function (state) { // 用普通函数this指向vue实例,但是在箭头函数中this就不是指向vue实例了,所以这里必须用普通哈数return this.tempcount + state.count},countplustempcount2 (state) {return this.tempcount2 + state.count}   })
}
</script>

我们继续看上面的mapState函数

computed: mapState({count: 'count',  // string    映射 this.count 为 store.state.count的值// 箭头函数可使代码更简练name: (state) => state.name, // function   映射 this.name 为 store.state.name的值nameAlias: 'name', // string   映射 this.nameAlias 为 store.state.name的值countplustempcount: function (state) { // 用普通函数this指向vue实例,但是在箭头函数中this就不是指向vue实例了,所以这里必须用普通哈数return this.tempcount + state.count},countplustempcount2 (state) {return this.tempcount2 + state.count}
})
  • 上面mapState()函数接收了一个对象。

对象的第一个属性是string类型的,count: ‘count’, 这条语句映射出了this.count, 值等于store.state.count的值。

对象的第二个属性是一个箭头函数,name: (state) => state.name,,映射 this.name 为 store.state.name的值。

对象的第三个属性是一个string类型,nameAlias: ‘name’,映射 this.nameAlias 为 store.state.name的值, 和第一个属性的用法本质是一致的,不过这里映射出的计算属性的名称与 state 的子节点名称不同。

对象的第四个属性是一个普通函数,普通函数和箭头函数的不同之处在于,普通函数中的this指向了vue实例,因为可以访问到当前组件的局部状态,比如this.tempcount。

对象的第五个属性是一个普通函数,第五个和第四个的用法本质是一样的,只不过第五个用了ES6中对象的简化写法。

  • 上面的mapState函数的返回值是一个对象,我们可以看作是这样的
computed:
{ // 这个对象就是mapState的返回值count () {return this.$store.state.count},name () {return this.$store.state.name}nameAlias () {return this.$store.state.name}countplustempcount: function (state) {return this.tempcount + this.$store.state.count},countplustempcount2 (state) {return this.tempcount2 + this.$store.state.count}
}

把这个对象赋值给computed不就和原始的写法一样了吗,所以mapState起到了简化的作用。但是我们可以发现比起直接给computed赋值,这里少了tempCountPlusTempCount2这个计算属性。tempCountPlusTempCount2不是有vuex状态计算而来的,是根据组件内的局部状态计算来的。

mapState函数结合对象的扩展运算符运算符使用

对象的扩展运算符(…)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。为什么要用扩展运算符呢,我们观察到上面直接将mapState函数的返回值赋给computed对象的话,那么computed中就只有对vuex状态的获取,而没有了当前组件的局部状态,比如tempCountPlusTempCount2就没地方放了,所以我们用扩展运算符。

let z = { a: 3, b: 4 };
let n = { ...z }; // 对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
n // { a: 3, b: 4 }

所以利用扩展运算符将下面mapState函数的返回值对象

computed:{...mapState({count: 'count',  // string    映射 this.count 为 store.state.count的值// 箭头函数可使代码更简练name: (state) => state.name, // function   映射 this.name 为 store.state.name的值nameAlias: 'name', // string   映射 this.nameAlias 为 store.state.name的值countplustempcount: function (state) { // 用普通函数this指向vue实例,但是在箭头函数中this就不是指向vue实例了,所以这里必须用普通哈数return this.tempcount + state.count},countplustempcount2 (state) {return this.tempcount2 + state.count} })
}

上面的结果等于

computed:{count () {return this.$store.state.count},name () {return this.$store.state.name}nameAlias () {return this.$store.state.name}countplustempcount: function (state) {return this.tempcount + this.$store.state.count},countplustempcount2 (state) {return this.tempcount2 + this.$store.state.count}
}

于是可以将组将内的计算属性和获取vuex状态的计算属性写在一起了。

computed:{tempCountPlusTempCount2() { return this.tempcount+this.tempcount2}, ...mapState({count: 'count',  // string    映射 this.count 为 store.state.count的值// 箭头函数可使代码更简练name: (state) => state.name, // function   映射 this.name 为 store.state.name的值nameAlias: 'name', // string   映射 this.nameAlias 为 store.state.name的值countplustempcount: function (state) { // 用普通函数this指向vue实例,但是在箭头函数中this就不是指向vue实例了,所以这里必须用普通哈数return this.tempcount + state.count},countplustempcount2 (state) {return this.tempcount2 + state.count} })
}

这就是mapState的基本用法。

mapState函数接受一个数组
当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。

computed: mapState([// 映射 this.count 为 store.state.count'count','name'
])

上面的写法可以看作

computed: {count () {return this.$store.state.count},name () {return this.$store.state.name}
}

最终版的mapState

computed: {tempCountPlusTempCount2() { return this.tempcount+this.tempcount2}, ...mapState(['count','name']),...mapState({nameAlias: 'name', // string   映射 this.nameAlias 为 store.state.name的值countplustempcount: function (state) { // 用普通函数this指向vue实例,但是在箭头函数中this就不是指向vue实例了,所以这里必须用普通哈数return this.tempcount + state.count},countplustempcount2 (state) {return this.tempcount2 + state.count} })
}

二、mapMutations

mapMutations是vuex的mutation的辅助函数,用于在组件中映射mutation内的方法,以便在该组件中直接使用mutation里的方法 (说白了,就是一语法糖)
1.在组件中导入vuex中的mapMutations:

import { mapMutations } from 'vuex'

2.在组件中导入mutation里的方法名:

...mapMutations([   //使用es6的拓展运算符'INCREASE_SHOPCART',   'DECREASE_SHOPCART'   ])
//约定将mutation里的方法名为大写,并且导入时要给其加上引号

举个栗子:点击btn按钮增减商品数量

//shopCart.vue
//template<button class="fl" @click='decrease(item.id)'>-</button><input type="number" class="fl" v-model="item.count"  ><button class="fl" @click='increase(item.id)'>+</button>
//mutations.js
INCREASE_SHOPCART(state,id){state.shopCartData.forEach(e=>{if(e.id === id){e.count ++}})},DECREASE_SHOPCART(state,id){state.shopCartData.forEach(e=>{if(e.id === id && e.count >1){e.count --}})}
import { mapMutations } from 'vuex' // 先从vuex里导入 mapMutations
methods:{...mapMutations([  'INCREASE_SHOPCART', //将mutation里的方法映射到该组件内'DECREASE_SHOPCART'  //等同于this.$store.commit('DECREASE_SHOPCART')  ]),increase(id){this.INCREASE_SHOPCART(id)
//由于上一步已经将mutation映射到组件内,所以组件可以直接调用INCREASE_SHOPCART  }decrease(id){this.DECREASE_SHOPCART(id)
//同理}
}

三、mapActions

actions功能与mutations相近,区别主要有以下两点:

  • actions不能直接改变state,只能通过调用mutation来改变state(mutations不能调用mutations,但是actions可以);
  • mutations只能执行同步操作,而actions可以执行异步操作。

如果我们把state、getters、mutations和actions一股脑全部定义在一个文件里,会导致Vuex的定义文件非常臃肿,因此在下面的例子里我们尝试把actions拆出来。首先需要单独定义actions(新增文件路径为src\store\action.js),代码如下:

export default {// context对象中包含state、commit和dispatch,分别对应Vuex中的state、执行mutations方法和执行actions方法action1: context => {setTimeout(() => {context.commit("mutation1");}, 1000);}
};

然后在Vuex中引入并声明actions(修改文件路径为src\store\index.js),代码如下:

import Vue from "vue";
import Vuex from "vuex";import action from "./action";Vue.use(Vuex);const store = new Vuex.Store({state: {param1: "state param"},getters: {param2: state => {return `new ${state.param1}`;},// 在getters中可以使用其他gettersparam3: (state, getters) => {return `another ${getters.param2}`;},// getter支持返回一个函数param4: state => index => {return state.paramArray[index];}},// mutations不支持相互调用(如下面的mutation1不能调用mutation2)mutations: {mutation1: state => {// 在mutations的回调函数内可以修改state的值state.param1 += " add something";},// mutations支持传递参数(第二个参数)mutation2: (state, addString) => {state.param1 += addString;}},actions: action
});export default store;

接下来在组件中引入并调用(新增文件路径为src\components\componentG.vue),代码如下:

<template><div><span>actions和mapActions用法</span><br /><span>state in vuex:{{param1}}</span><br /><button @click="action1()">mapActions</button></div>
</template><script>
import { mapState, mapActions } from "vuex";
export default {name: "component-g",computed: {...mapState(["param1"])},methods: {...mapActions(["action1"])// action1() {//     // 通过this.$store.dispatch("actions方法名")的方式可以调用actions,当然,定义...mapActions(["action1"])然后直接写this.action1();肯定更方便//     this.$store.dispatch("action1");// }}
};
</script><style scoped>
</style>

eg:登录后调用获取实体图标的接口



Vuex状态管理-mapState、mapMutations、mapActions相关推荐

  1. Vuex状态管理-mapState的基本用法详细介绍

    使用vuex集中管理状态 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 // store. ...

  2. 在vue项目中引用vuex状态管理工具

    在vue项目中引用vuex状态管理工具 一.vuex是什么? 二.使用步骤 1.引入库 2.在main.js文件引入配置 3.配置store/index.js文件 4.获取state数据 5.获取ge ...

  3. vuex状态管理,用最朴实的话讲解最难懂的技术,

    一.案例演示 引入vuex 1.利用npm包管理工具,进行安装 vuex.在控制命令行中输入下边的命令就可以了. npm n install vuex --save 需要注意的是这里一定要加上 –sa ...

  4. [vuex]状态管理vuex

    vuex 状态管理vuex,之前一般都是通过一个全局js文件实现全局设置,在vue中通过vuex进行管理 简介 vuex是专为vue.js应用程序开发的状态管理模式.它采用集中存储管理应用的所有组件的 ...

  5. vue2项目复习01-关闭elint检校,src文件别名,路由传参的对象写法,代理解决跨域问题,nprogress,vuex状态管理库,store的模块式开发,节流与防抖,编程式导航+事件委托路由跳转

    1.关闭elint语法校验 创建vue.config.js //关闭elint语法校验 {lintOnSave:false; } 2.src文件夹配置别名 jsconfig.json配置别名 @代表s ...

  6. Vuex 状态管理的工作原理

    Vuex 状态管理的工作原理 为什么要使用 Vuex 当我们使用 Vue.js 来开发一个单页应用时,经常会遇到一些组件间共享的数据或状态,或是需要通过 props 深层传递的一些数据.在应用规模较小 ...

  7. 【3D商城】使用Vuex状态管理完成购物车模块

    [3D商城]使用Vuex状态管理完成购物车模块 创建购物车的全局数据 添加产品到购物车 导航栏的购物车模块 结果 常见问题总结 创建购物车的全局数据 在store的index.js中 ,创建购物车变量 ...

  8. Vue项目 成员管理系统 Vuex状态管理(10)

    Vuex是一个专为Vue.js应用程序开发的状态管理模式.它采用集中式储存管理应用的所有组件的转台并以相应的规则保证装填以一中可预测的方式发生变化. Vuex可以将组件中的某些属性.值或者方法拿出来统 ...

  9. 【vuex状态管理案例mutations和actions区别】

    目录 vuex 状态管理 传统组件传值的缺点 案例 加减 效果 现在我们希望它是两个计数器的数同时加加减~ 先来看一下减的 父组件 子组件 加的是一样的逻辑哦 虽然这样可以实现我们想要的效果但是,还是 ...

最新文章

  1. stm32 内部sram大小_STM32第三天
  2. NYOJ 664 数字整除
  3. JAVA使用JDBC连接MySQL数据库
  4. sqlite 模糊匹配日期_SQLite模糊查找(like) | 学步园
  5. Spring容器创建流程(7)事件派发机制
  6. 优秀文章收集,也有专题,改变了我的一些看法。
  7. 从零基础入门Tensorflow2.0 ----五、25TF1.0自定义estimator
  8. Oracle 11gR2 中 示例用户 安装说明
  9. centos进入管理员_centOS 如何让当前用户取得管理员权限
  10. WebClient发布到IIS后访问共享文件提示用户名或密码错误(已设置凭证)
  11. CodeForces 372A Counting Kangaroos is Fun 动物PK
  12. 解决使用maven打jar包缺失依赖包问题
  13. 裸机搭建深度学习服务器,ubuntu ssh服务器,pytorch, tensorflow, paddle三种框架安装。以及各种避雷。
  14. GPIO寄存器原理与操作
  15. mac vscode改变字体
  16. RDS数据库申请外网地址
  17. Adaptive Personalized Federated Learning 论文解读+代码解析
  18. opencv 训练样本
  19. python-读取和保存npy文件
  20. 2018年个人所得税Excel计算公式

热门文章

  1. 达人评测 i7 13790F和i5 13490f选哪个好
  2. 调试“侦探的利器”!!!
  3. 【洛谷P7960】[NOIP2021] 报数【筛法】
  4. SpringBoot整合mybatis+mybatis分页插件
  5. r生成新的dataframe_R 语言的Dataframe常用操作
  6. C++蠕虫病毒免疫器 (antiAutoRun)
  7. 纽约时报杂志的年度创意大赏 (ZT)
  8. Ubuntu双系统的安装(有U盘就行)
  9. python如何剪辑音频_剪辑音乐要很久?3行语句Python瞬间搞定
  10. 手机用移动电源选什么品牌好,实惠好用的移动电源推荐