5.3.Vuex的核心概念

store: 每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)

state:包含所有应用级别状态的对象

Getter: 在组件内部获取store中状态的函数,可以认为是 store 的计算属性

Mutation: 唯一修改状态的事件回调函数

Action:Action 类似于 mutation,不同在于:1、Action 提交的是 mutation,而不是直接变更状态。2、Action 可以包含任意异步操

Modules: 将store分割成不同的模块

5.3.1.Mutation

注意; 在Mutation中,是不能提交异步代码的,例如:

import Vue from 'vue'
import Vuex from 'vuex' // 让vuex作为vue的插件来使用
Vue.use(Vuex) // 创建一个容器
let store = new Vuex.Store({
state: {
goods_num: 0
},
mutations: {
changeCar (state, num) {
console.log(state)
setTimeout(() => {
state.goods_num += num
}, 2000)
}
}
}) // 把这个store实例导出 方便在vue中注入
export default store

5.3.2.Action

在mutation中提交异步代码,状态的改变是没办法追踪的,如果有异步代码,需要放到Action中去,等异步代码执行完成后再提交 store/index.js中的代码

import Vue from 'vue'
import Vuex from 'vuex' // 让vuex作为vue的插件来使用
Vue.use(Vuex) // 创建一个容器
let store = new Vuex.Store({
state: {
goods_num: 0
},
mutations: {
changeCar (state, num) {
state.goods_num += num
}
},
actions: {
changeCarAction (context, num) {
console.log(context)
setTimeout(() => {
context.commit('changeCar', num)
}, 2000)
}
}
}) // 把这个store实例导出 方便在vue中注入
export default store

触发这个action,在VuexGoodsItem中去修改

export default {
data () {
return {
num: 12
}
},
components: { },
methods: {
increase () {
this.num++
},
decrease () {
this.num--
},
addCar () {
// this.$store.commit('changeCar', this.num)
this.$store.dispatch('changeCarAction', this.num)
}
}
}

如果上面的都搞定了,再来看执行的流程图就轻松了

5.3.3.Getter

Getter可以认为是 store 的计算属性,可以对数据进行处理。为了掩饰效果,我们新建一个Count组件来说明

<template>
<div class="page">
<span>{{this.$store.state.count}}</span>
<button @click="increase">+</button>
</div>
</template> <script type="text/ecmascript-6">
export default {
data () {
return { }
},
components: { },
methods: {
increase () {
this.$store.commit('add')
}
}
}
</script> <style scoped>
.page{
width: 300px;
margin: 100px auto
}
</style>

在store中增加mutation函数和count变量,以下是部分代码

  state: {
goods_num: 0,
count: 0
},
mutations: {
changeCar (state, num) {
state.goods_num += num
},
add (state) {
state.count++
}
}

这样我们就实现了vuex版的加法计数器,如果对count这个变量有一些逻辑判断怎么办呢?我们可以在组件内部使用computed来实现,如果这个逻辑是全局通用的,你可以把它放到Getter里面去,举例:

需求:当计数器加到10的时候就不能继续加了

在store中增加getters选项

import Vue from 'vue'
import Vuex from 'vuex' // 让vuex作为vue的插件来使用
Vue.use(Vuex) // 创建一个容器
let store = new Vuex.Store({
state: {
goods_num: 0,
count: 0
},
mutations: {
changeCar (state, num) {
state.goods_num += num
},
add (state) {
state.count++
}
},
actions: {
changeCarAction (context, num) {
console.log(context)
setTimeout(() => {
context.commit('changeCar', num)
}, 2000)
}
},
getters: {
newCount (state) {
return state.count > 10 ? 10 : state.count
}
}
}) // 把这个store实例导出 方便在vue中注入
export default store

使用到时候,从store.getters对象中去获取

<p><span>{{this.$store.getters.newCount}}</span></p>

注意:如果要给getters里面的函数传参数,需要写成这样

  getters: {
newCount (state) {
return state.count > 10 ? 10 : state.count
},
newCount2 (state) {
// 返回一个函数
return (num) => state.count > num ? num : state.count
}
}

调用的时候,这样调用

<p><span>{{this.$store.getters.newCount2(5)}}</span></p>

5.3.4.辅助函数mapState、mapGetters、mapActions

这几个辅助函数可以帮助我们简化一些写法

注意:在使用之前一定要先引入

import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'

1.mapState,这个函数是和computed的映射,可以把传入mapState的对象或者数组,转化成计算属性

mapState里面可以传入数组和对象,首先来看传入数组的写法


computed: {
...mapState(['num3', 'num4', 'num5'])
}

注意,这里传入的num3、num4、num5需要和state里面定义的状态同名

state: {
goods_num: 0,
count: 0,
num3: 9,
num4: 10,
num5: 11
}

这样写就可以直接去批量拿到state里面的数据,不用再去使用this.$store.state.num3 来获取值了,这就是辅助函数的作用,可以简化一些写法

有些时候,我们需要从state里面取值进行处理,例如这样:

computed: {
num3 () {
return this.$store.state.num3 > 10 ? 10 : 20
}
}

如果使用辅助函数,我们就需要以对象的形式传入了

computed: {
// num3 () {
// return this.$store.state.num3 > 10 ? 10 : 20
// }
...mapState({
num3: state => state.num3 > 10 ? 10 : 20
})
}

使用箭头函数可以简化代码,同时还可以给state里的状态重命名,例如:

computed: {
// num3 () {
// return this.$store.state.num3 > 10 ? 10 : 20
// }
...mapState({
num3: state => state.num3 > 10 ? 10 : 20,
num100: 'num4' //给num4 取一个别名 num4
})
}

如果你要使用this这个关键字,就不能用箭头函数,因此,可以简写成这样

computed: {
// num3 () {
// return this.$store.state.num3 > 10 ? 10 : 20
// }
...mapState({
num3: state => state.num3 > 10 ? 10 : 20,
num100: 'num4',
num6 (state) {
//需要取data里面的num99和state里面的num6相加,这个时候需要用到this
return this.num99 + state.num6
}
})
}

以上就是mapState的基本用法,mapMutations、mapGetters、mapActions的用法也一样, 简单举例:

//mapMutations的用法
methods: {
// increase () {
// this.$store.commit('add')
// }
...mapMutations({
increase: 'add'
})
}
//mapActions的用法
methods: {
// increase () {
// this.$store.commit('add')
// }
...mapMutations({
increase: 'add'
}),
// decrease () {
// this.$store.dispatch('decreaseAction')
// },
...mapActions({
decrease: 'decreaseAction'
})
},
//mapGetters的用法
computed: {
// num3 () {
// return this.$store.state.num3 > 10 ? 10 : 20
// }
...mapState({
num3: state => state.num3 > 10 ? 10 : 20,
num100: 'num4',
num6 (state) {
return this.num99 + state.num6
}
}),
...mapGetters({
num5: 'newCount'
})
}

5.3.5.Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块, 下面是我们的store/index.js文件,我们可以尝试将其拆分一个子模块出来

import Vue from 'vue'
import Vuex from 'vuex' // 让vuex作为vue的插件来使用
Vue.use(Vuex) // 创建一个容器
let store = new Vuex.Store({
state: {
goods_num: 0,
//下面状态是count组件里面的状态
count: 0,
num3: 9,
num4: 10,
num5: 11,
num6: 6
},
mutations: {
changeCar (state, num) {
state.goods_num += num
},
//下面方法是count里面的方法
add (state) {
state.count++
},
decreaseMutation (state) {
state.count--
}
},
actions: {
changeCarAction (context, num) {
console.log(context)
setTimeout(() => {
context.commit('changeCar', num)
}, 2000)
},
//下面方法是count里面的方法
decreaseAction (context) {
setTimeout(() => {
context.commit('decreaseMutation')
}, 1000)
}
},
getters: {
//下面方法是count里面的方法
newCount (state) {
return state.count > 10 ? 10 : state.count
},
newCount2 (state) {
return (num) => state.count > num ? num : state.count
}
}
}) // 把这个store实例导出 方便在vue中注入
export default store

下面开始拆分

1 自定义一个对象

 // 直接定义一个子模块
let countModule = {
state: {
count: 0,
num3: 9,
num4: 10,
num5: 11,
num6: 6
},
mutations: {
add (state) {
state.count++
},
decreaseMutation (state) {
state.count--
}
},
actions: {
decreaseAction (context) {
setTimeout(() => {
context.commit('decreaseMutation')
}, 1000)
}
},
getters: {
newCount (state, getters, rootState) {
return state.count > 10 ? 10 : state.count
},
newCount2 (state) {
return (num) => state.count > num ? num : state.count
}
}
}

2 将这个对象挂在store上

// 创建一个容器
let store = new Vuex.Store({
state: {
goods_num: 0
},
mutations: {
changeCar (state, num) {
state.goods_num += num
}
},
actions: {
changeCarAction (context, num) {
console.log(context)
setTimeout(() => {
context.commit('changeCar', num)
}, 2000)
}
},
modules: {
countModule //子模块
}
})

完整代码:

import Vue from 'vue'
import Vuex from 'vuex' // 让vuex作为vue的插件来使用
Vue.use(Vuex) // 直接定义一个子模块
let countModule = {
state: {
count: 0,
num3: 9,
num4: 10,
num5: 11,
num6: 6
},
mutations: {
add (state) {
state.count++
},
decreaseMutation (state) {
state.count--
}
},
actions: {
decreaseAction (context) {
setTimeout(() => {
context.commit('decreaseMutation')
}, 1000)
}
},
getters: {
newCount (state, getters, rootState) {
return state.count > 10 ? 10 : state.count
},
newCount2 (state) {
return (num) => state.count > num ? num : state.count
}
}
} // 创建一个容器
let store = new Vuex.Store({
state: {
goods_num: 0
},
mutations: {
changeCar (state, num) {
state.goods_num += num
}
},
actions: {
changeCarAction (context, num) {
console.log(context)
setTimeout(() => {
context.commit('changeCar', num)
}, 2000)
}
},
modules: {
countModule
}
}) // 把这个store实例导出 方便在vue中注入
export default store

5.5.什么时候使用vuex

虽然 Vuex 可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

螺钉课堂视频课程地址:http://edu.nodeing.com

vue全家桶(4.3)的更多相关文章

  1. 用 Vue 全家桶二次开发 V2EX 社区

    一.开发背景 为了全面的熟悉Vue+Vue-router+Vuex+axios技术栈,结合V2EX的开放API开发了这个简洁版的V2EX. 在线预览 (为了实现跨域,直接npm run dev部署的, ...

  2. Vue全家桶

    简介 “简单却不失优雅,小巧而不乏大匠”. Vue.js 是一个JavaScriptMVVM库,是一套构建用户界面的渐进式框架.它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计. 为什么 ...

  3. 从零开始系列之vue全家桶(3)安装使用vuex

    什么是vuex? vuex:Vue提供的状态管理工具,用于同一管理我们项目中各种数据的交互和重用,存储我们需要用到数据对象. 即data中属性同时有一个或几个组件同时使用,就是data中共用的属性. ...

  4. 使用vue全家桶制作博客网站

    前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用vue全家桶制作的博客网站 概述 该项目是基于vue全家桶(vue.vue-router.vuex.v ...

  5. 转载: 使用vue全家桶制作博客网站 HTML5 移动网站制作的好教程

    使用vue全家桶制作博客网站   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用vue全家桶制作的博客网站 概述 该项目是基于vue全家桶(vue. ...

  6. Vue全家桶介绍

    一直不清楚全家桶是什么玩意,上网搜了一下,才知道就是平时项目中使用的几个依赖包,下面分享一下 Vue 全家桶介绍 Vue有著名的全家桶系列,包含了vue-router(http://router.vu ...

  7. 一个简单的假vue全家桶(vue+vue-router+require)

    首先说明我觉得这是一个比较好理解的vue全家桶(虽然是假的),模块化也是用require来做的,而且如果后期有必要压缩我也会用gulp来做 1.依赖个个本地模块,require只是用来载入page,这 ...

  8. Vue 全家桶 + Electron 开发的一个跨三端的应用

    代码地址如下:http://www.demodashi.com/demo/11738.html GitHub Repo:vue-objccn Follow: halfrost · GitHub 利用 ...

  9. Vue全家桶了解一下(待补充)

    vue全家桶了解一下 一.vue+vue-router+vuex+axios1.vue:使用vue-cli,生成最基本的vue项目2.vue-router:vue项目中的路由管理插件3.vuex:vu ...

  10. 升级vue全家桶过程记录

    背景 如果你使用了element-ui的el-tabs组件,并且想要单独升级element-ui至2.10.0,你会发现,使用了el-tabs组件的页面只要打开就卡死.原因是element-ui~2. ...

随机推荐

  1. Rocket - util - Timer

    https://mp.weixin.qq.com/s/Z4JJhZ_jL1lqF1nf_orq9A   简单介绍Timer的实现.   ​​   1. 基本功能   实现定时器的功能.   2. Ti ...

  2. 【Linux】将javaweb项目部署到CentOS的tomcat上

    1.将项目打包成war包 build之后war文件就生成了. 2.拷贝war文件到CentOS的tomcat的项目文件夹中 用WinSCP将文件粘帖进这个文件夹中 /wocloud/tomcat_cl ...

  3. java实现第四届蓝桥杯猜灯谜

    猜灯谜 题目描述 A 村的元宵节灯会上有一迷题: 请猜谜 * 请猜谜 = 请边赏灯边猜 小明想,一定是每个汉字代表一个数字,不同的汉字代表不同的数字. 请你用计算机按小明的思路算一下,然后提交&quo ...

  4. java实现第六届蓝桥杯打印大X

    打印大X 打印大X 小明希望用星号拼凑,打印出一个大X,他要求能够控制笔画的宽度和整个字的高度. 为了便于比对空格,所有的空白位置都以句点符来代替. 要求输入两个整数m n,表示笔的宽度,X的高度.用 ...

  5. python—模块与包

    模块: (一个.py文件就是一个模块module,模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能.) 模块分三种: 1.python标准库 2.第三方模块 3.应用程序自定义模块 ...

  6. Python内存管理机制-《源码解析》

    Python内存管理机制 Python 内存管理分层架构 /* An object allocator for Python. Here is an introduction to the layer ...

  7. Java基础(十)

    一.XML概述 属性文件是用来描述程序配置,属性文件包含了一组名/值对.属性文件采用的是一种单一的平面层次结构,同时属性文件要求键是唯一的. XML格式能够表达层次结构,并且重复的元素不会被曲解. H ...

  8. Linux内核配置编译及基本调试方法

    一.Linux内核配置编译 1. 交叉编译设置:make ARCH=arm CROSS_COMPILE=arm-linux- 注:也可以直接修改顶层Makefile ARCH ?= arm CROSS ...

  9. 你真的了解EF吗?关于EntityFramework的高级优化

    接上一篇文章.现在写程序,做项目不是说功能做完就完事了,在平常的开发过程中对于性能的考虑也是极其重要的. 关于ef的那些事,今天就来说说吧.首先必须得知道.net ef在程序中的五种状态变化过程与原理 ...

  10. 96题--不同的二叉搜索树(java、中等难度)

    题目描述:给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例如下: 分析:本题可用动态规划的方法求解. 设 dp[n] 表示以 1 ... n 为节点组成的二叉搜索树的种类 ...