我们的项目非常简单,当点击+1按钮的时候,count 加1,点击-1按钮的时候,count 减1.

1, mutation

  The only way to actually change state in a Vuex store is by committing a mutation, 在vue 中,只有mutation 才能改变state.  mutation 类似事件,每一个mutation都有一个类型和一个处理函数,因为只有mutation 才能改变state, 所以处理函数自动会获得一个默认参数 state. 所谓的类型其实就是名字,action去comit 一个mutation, 它要指定去commit哪个mutation, 所以mutation至少需要一个名字,commit mutation 之后, 要做什么事情,那就需要给它指定一个处理函数, 类型(名字) + 处理函数就构成了mutation. 现在store.js添加mutation.

const store = new Vuex.Store({
state: {
count:0
},
mutations: {
// 加1
increment(state) {
state.count++;
},
// 减1
decrement(state) {
state.count--
}
}
})

  Vue 建议我们mutation 类型用大写常量表示,修改一下,把mutation 类型改为大写

mutations: {
// 加1
INCREMENT(state) {
state.count++;
},
// 减1
DECREMENT(state) {
state.count--
}
}

2, action

action去commit mutations, 所以还要定义action. store.js 里面添加actions.

const store = new Vuex.Store({
state: {
count:0
},
mutations: {
// 加1
INCREMENT(state) {
state.count++;
},
// 减1
DECREMENT(state) {
state.count--
}
},
actions: {
increment(context) {
context.commit("INCREMENT");
},
decrement(context) {
context.commit("DECREMENT");
}
}
})

  action 和mutions 的定义方法是类似的,我们要dispatch 一个action, 所以actions 肯定有一个名字,dispatch action 之后它要做事情,就是commit mutation, 所以还要给它指定一个函数。因为要commit mutation ,所以 函数也会自动获得一个默认参数context,  它是一个store 实例,通过它可以获取到store 实例的属性和方法,如 context.state 就会获取到 state 属性, context.commit 就会执行commit命令。

  其实actions 还可以简写一下, 因为函数的参数是一个对象,函数中用的是对象中一个方法,我们可以通过对象的解构赋值直接获取到该方法。修改一下 actions

actions: {
increment({commit}){
commit("INCREMENT")
},
decrement({commit}){
commit("DECREMENT")
}
}

3, dispatch  action

  现在就剩下dispatch action 了。什么时候dispatch action 呢? 只有当我们点击按钮的时候. 给按钮添加click 事件,在click 事件处理函数的中dispatch action.

  打开increment.vue 组件,给两个按钮添加click 事件。

<template>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
</template> <script>
export default {
methods: {
increment(){
this.$store.dispatch("increment");
},
decrement() {
this.$store.dispatch("decrement")
}
}
}
</script>

  其实像上面dispatch action 比较麻烦,如果有10 个按钮,我们要写10 个函数,且存在大量的重复,并且我们的事件处理函数名字和action的名字是一样的,这时vue  提供了mapAction 函数,它和mapState  是一样的,把我们的 action 直接映射到store 里面的action中。

  像这种组件中的事件处理函数名字和action的名字是相同的,直接把 事件处理函数名字放到一个数组中。组件中的methods 修改如下:

<script>
import {mapActions} from "vuex";
export default {
methods: {
...mapActions(["increment", "decrement"])
}
}
</script>

  如果事件处理函数名字和action的名字不同,给mapActions 提供一个对象,对象的属性是事件处理函数名字, 属性值是 对应的dispatch 的action 的名字。

  我们把 +1 按钮的事件处理函数变改为 add,代码如下:

<template>
<div>
<button @click="add">+1</button> <!-- 事件处理函数变为add -->
<button @click="decrement">-1</button>
</div>
</template> <script>
import {mapActions} from "vuex";
export default {
methods: {
...mapActions(["decrement"]),        // mapActions 对应做出改变
...mapActions({
add: "increment"
})
}
}

这时候我们单击按钮,就可以看到count 发生变化。

通过vuex 传递参数

  很多时候,组件和组件之间还要传递参数,这些都要经过vuex。 在increment 组件内部增加一个输入框和一个按钮,点击按钮的时候,count 增加输入框内的值。

<template>
<div>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
    // 增加内容
<div>
<input type="text" v-model="incrementValue">
<button @click="incrementWithValue">increment</button>
</div>
</div>
</template>

  在组件内部dispatch action 的时候,它可以自定义参数,只要参数在它dispatch 的action名称 后面,依次列出来就可以了。 在这里,我们点击按钮的时候,触发一个incrementWithValue  action, 并且带一个参数,就可以这样写 this.$store.dispatch(“incrementWithValue”, value), 整个increment.vue 组件如下:

<template>
<div>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
<div>
<input type="text" v-model="incrementValue">
<button @click="incrementWithValue">increment</button>
</div>
</div>
</template> <script>
import {mapActions} from "vuex";
export default {
data() {
return {
incrementValue: 0
}
},
methods: {
...mapActions(["increment","decrement"]),
incrementWithValue() {
this.$store.dispatch("incrementWithValue", this.incrementValue)
}
}
}
</script>

  同样,actions 和mutations 中的处理函数也是一样,它除了可以得到默认参数外,还可以接受自定义的参数,我们自定义的参数,依次在默认参数后面列出来就可以了。 在store.js中分加增加incrementWithValue action和 INCREMENT_WITH_VALUE mutation

const store = new Vuex.Store({
state: {
count:0
},
mutations: {
// 加1
INCREMENT(state) {
state.count++;
},
// 减1
DECREMENT(state) {
state.count--
},
INCREMENT_WITH_VALUE(state, value){
state.count +=value;
}
},
actions: {
increment({commit}){
commit("INCREMENT")
},
decrement({commit}){
commit("DECREMENT")
},
incrementWithValue({commit}, value){
commit("INCREMENT_WITH_VALUE", parseInt(value))
}
}
})

 错误处理

  当我们给vuex 传参的时候,我们要检测参数的正确性,如果有错误需要进行处理

  action 中如果是同步操作,就用try..catch 语句,组件中使用try…catch, 捕获action中抛出的错误。Increment.vue 组件中,incrementWithValue() 方法中修改如下:

methods: {
...mapActions(["increment","decrement"]),
incrementWithValue() {
try {
this.$store.dispatch("incrementWithValue", this.incrementValue)
}catch(error) {
alert(error)
}
}
}

  同时store.js 中的action 也进行如下修改:

incrementWithValue({commit}, value){
let intValue = parseInt(value);
if(isNaN(intValue)){
throw "Not an Interger"
}else {
commit("INCREMENT_WITH_VALUE", intValue)
}
}

  如果action 中进行的是异步操作,那就需要在回调函数中进行错误处理。

incrementWithValue({commit}, value){
let intValue = parseInt(value)
setTimeout(function() { if(isNaN(intValue)) {
alert("Not an Interger")
}else {
commit("INCREMENT_WITH_VALUE", intValue)
}
}, 2000)
}

异步操作给出用户提示信息

  首先,在我们的increment.vue中添加一个提示信息,简单给一个div 进行提示。用户提示信息的显示和隐藏,又涉及到一个状态,我们设为waiting, 需要在state 中进行添加。默认为false, 同时我们组件需要从state 中获取到初始状态。increment.vue 组件修改如下:

<template>
<div>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
<div>
<input type="text" v-model="incrementValue">
<button @click="incrementWithValue">increment</button>
</div>
<!-- 展示信息 -->
<div v-if ="show">
waiting
</div>
</div>
</template> <script>
import {mapActions} from "vuex";
export default {
data() {
return {
incrementValue: 0
}
},
    // computed 从state 中获取初始状态
computed: {
show: function() {
return this.$store.state.waiting;
}
},
methods: {
...mapActions(["increment","decrement"]),
incrementWithValue() {
this.$store.dispatch("incrementWithValue", this.incrementValue)
}
}
}
</script>

mutation 去操作状态,所以增加两个muatation, 用于显示和隐藏waiting. action 中去触发这两个mutation. 整个state 如下:

const store = new Vuex.Store({
state: {
count:0,
// 新增waiting 状态
waiting: false
},
mutations: {
// 加1
INCREMENT(state) {
state.count++;
},
// 减1
DECREMENT(state) {
state.count--
},
INCREMENT_WITH_VALUE(state, value){
state.count +=value;
},
// 显示和隐藏waiting
SHOW_WAITING_MESSAGE(state){
state.waiting = true;
},
HIDE_WAITING_MESSAGE(state){
state.waiting = false;
}
},
actions: {
increment({commit}){
commit("INCREMENT")
},
decrement({commit}){
commit("DECREMENT")
},
incrementWithValue({commit}, value){
commit("SHOW_WAITING_MESSAGE");
let intValue = parseInt(value)
setTimeout(function() {
if(isNaN(intValue)) {
alert("Not an Interger")
}else {
commit("HIDE_WAITING_MESSAGE");
commit("INCREMENT_WITH_VALUE", intValue)
}
}, 2000)
}
}
})

注意:

  mutation是同步的,只要comit muation, 它就会立即改变state , 这有利于我们追踪 状态的改变。如果 mution 之后,五分钟才改变state, 那就真不知道state 到底是哪个state了。

  action 是异步的,还有的错误处理也都在这里操作。

最新文章

  1. Microsoft Azure Web Sites应用与实践【4】—— Microsoft Azure网站的“后门”
  2. vc下的静态链接库与动态链接库(一)
  3. vi命令示例大全
  4. Saltstack系列5:Saltstack之pillar组件
  5. Word图片版式设置问题
  6. tranform-scale 缩小元素,移上去文字抖动
  7. 【html】【11】函数名称约束规范
  8. UM分享 - 详解
  9. 开源 免费 java CMS - FreeCMS2.0 会员我的评论
  10. 关于已经安装python为何还要安装python-dev
  11. Content Negotiation(内容协商)
  12. zookeeper系列之异步通知模式-Watcher
  13. BZOJ 1854: [Scoi2010]游戏 [连通分量 | 并查集 | 二分图匹配]
  14. vue兄弟之间传值 bus中央事件总线
  15. Raft 基础
  16. yii2 Gridview网格小部件
  17. java获取文件路径
  18. pta_l1-6(连续因子)
  19. CCF CSP 201512-2 消除类游戏
  20. window常用的快捷键

热门文章

  1. JavaScript输入表单数据正则验证规则
  2. 如何备份和恢复你的TFS服务器(三)
  3. 【转】DataTable与实体类互相转换
  4. Spark官方调优文档翻译(转载)
  5. docker环境搭建
  6. Centos7之Systemd(Service文件)详解
  7. Sparse Principal Component Analysis via Rotation and Truncation
  8. python中map()函数用法
  9. Linux查看硬件等基本参数
  10. ubuntu使用squid搭建代理