Vuex-Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
让我们来注册一个简单的 action:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit
提交一个 mutation,或者通过 context.state
和 context.getters
来获取 state 和 getters。当我们在之后介绍到 Modules 时,你就知道 context 对象为什么不是 store 实例本身了。
实践中,我们会经常用到 ES2015 的 参数解构 来简化代码(特别是我们需要调用 commit
很多次的时候):
actions: {
increment ({ commit }) {
commit('increment')
}
}
分发 Action
Action 通过 store.dispatch
方法触发:
store.dispatch('increment')
乍一眼看上去感觉多此一举,我们直接分发 mutation 岂不更方便?实际上并非如此,还记得 mutation 必须同步执行这个限制么?Action 就不受约束!我们可以在 action 内部执行异步操作:
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
Actions 支持同样的载荷方式和对象方式进行分发:
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
}) // 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
在组件中分发 Action
你在组件中使用 this.$store.dispatch('xxx')
分发 action,或者使用 mapActions
辅助函数将组件的 methods 映射为 store.dispatch
调用(需要先在根节点注入 store
):
import { mapActions } from 'vuex' export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')` // `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
组合 Action
Action 通常是异步的,那么如何知道 action 什么时候结束呢?更重要的是,我们如何才能组合多个 action,以处理更加复杂的异步流程?
首先,你需要明白 store.dispatch
可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch
仍旧返回 Promise:
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
现在你可以:
store.dispatch('actionA').then(() => {
// ...
})
在另外一个 action 中也可以:
actions: {
// ...
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
}
最后,如果我们利用 async / await,我们可以如下组合 action:
// 假设 getData() 和 getOtherData() 返回的是 Promise actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
一个 store.dispatch
在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行
运用举例
login.vue
login() {
this.error = "";
if (!this.username) {
this.error = "请输入用户名!";
return;
}
if (!this.passwd) {
this.error = "请输入密码!";
return;
}
var self = this;
this.$store
.dispatch("doLogin", {
username: this.username,
passwd: this.passwd
})
.then(resp => {
this.$cookie.set("session_id", resp.data.session_id, 1); //有效期1天
this.$cookie.set("username", resp.data.username, 1); //有效期1天
self.$store.commit("SAVE_AUTHENTICATION", resp.data);
self.$router.push({ path: "/index" });
});
}
/store/auth.js
import auth from "../../api/auth";
const VueCookie = require('vue-cookie') const user = {
state: {
username: "", // 用户名
session_id: "",
}, mutations: {
SAVE_AUTHENTICATION(state, auth) {
state.session_id = auth.session_id;
state.username = auth.username;
},
}, actions: {
doLogin({ commit }, user) {
var self = this;
return new Promise((resolve, reject) => {
auth
.login(user)
.then(resp => {
if (resp.status != 200) {
reject(resp.msg || "登录错误");
} else {
resolve(resp);
}
})
.catch(resp => {
console.error(resp);
reject("登录错误");
});
});
}
}, getters: {
username: state => {
if(!state.username){
state.username = VueCookie.get('username')
}
return state.username
}
}
}; export default user;
Vuex-Action的更多相关文章
- vuex action 与mutations 的区别
面试没说清楚.这个太丢人回来整理下: 事实上在 vuex 里面 actions 只是一个架构性的概念,并不是必须的,说到底只是一个函数,你在里面想干嘛都可以,只要最后触发 mutation 就行.异步 ...
- VUEX action解除页面耦合
最近项目中需要用到vue+vuex来实现登出跳转功能,老大指派任务要用action解除页面耦合,刚从vue深渊晕晕乎乎爬出来的我是一脸懵逼啊...啥是解除耦合...网上vuex的资料太少了,vuex手 ...
- 如何在 vuex action 中获取到 vue 实例
问题:在做运营开发工具的时候 我想要请求后台服务器保存成功后 弹出一个弹框(饿了吗 的 message 弹框), 由于$message 是挂在 Vue原型链上的方法 (Vue.prototype.$m ...
- vue-x action 的相互调用
实现方式:分发 Action Action 通过 store.dispatch 方法触发: store.dispatch('increment')
- vuex——action,mutation,getters的调用
一.子模块调用根模块的方法 mutation调用 context.commit('clearloginInfo',{key_root:data},{root:true}); action调用 co ...
- vuex(1.0版本写法)
Vuex 是一个专门为 Vue.js 应用所设计的集中式状态管理架构. 官方文档:http://vuex.vuejs.org/zh-cn/ 2.0和1.0都能在此找到 每一个 Vuex 应用的核心就 ...
- vue+vue-cli+vuex+vrouter 开发学习和总结
1.项目目录结构 1.components------------------------->页面中所用的公共组件: 2.router index.js -------------------- ...
- [Nuxt] Update State with Vuex Actions in Nuxt.js
You can conditionally add classes to Vue.js templates using v-bind:class. This will help display the ...
- [Nuxt] Build a Vue.js Form then use Vuex Actions to Post to an API in Nuxt
The default behavior of submitting an HTML form is to reload the page. You can use the Vue.js @submi ...
- vue组件通信传值——Vuex
一.Vuex介绍 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. Vuex 也集成到 Vu ...
随机推荐
- Spring Cloud构建微服务架构
Dalston版本 由于Brixton和Camden版本的教程已经停止更新,所以笔者计划在2017年上半年完成Dalston版本的教程编写(原计划完成Camden版本教程,但由于写了两篇Dalston ...
- Ajax修改全局变量问题解决方法(Zepto版)
前两天项目遇到一个用ajax修改全局变量的案例,一开始无法给这个全局变量修改赋值,在网上查了一下,解决如下: 修改前: var word=1; $.ajax({ url:"myJSON.js ...
- 第123天:移动web开发中的常见问题
一.函数库 underscoreJS _.template: <ol class="carousel-indicators"> <!--渲染的HTML字符串--& ...
- Javascript中判断变量是数组还是对象(array还是object)
怎样判断一个JavaScript变量是array还是obiect? 答案: 1.如果你只是用typeof来检查该变量,不论是array还是object,都将返回‘objec'. 此问题的一个可行的答案 ...
- bzoj2301-Problem b
题意 \(T\le 5\times 10^4\) 次询问,每次询问 \(a,b,c,d,k\le 5\times 10^4\),求 \[ \sum _{i=a}^b\sum _{j=c}^d[gcd( ...
- 洛谷 P1678 烦恼的高考志愿
题目背景 计算机竞赛小组的神牛V神终于结束了万恶的高考,然而作为班长的他还不能闲下来,班主任老t给了他一个艰巨的任务:帮同学找出最合理的大学填报方案.可是v神太忙了,身后还有一群小姑娘等着和他约会,于 ...
- 【UOJ#79】一般图最大匹配(带花树)
[UOJ#79]一般图最大匹配(带花树) 题面 UOJ 题解 带花树模板题 关于带花树的详细内容 #include<iostream> #include<cstdio> #in ...
- js new date()说明
javaScript UTC() 方法: UTC() 方法可根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数. 要创建一个一个日期对象,可以使用以下的方式: var now=new D ...
- C++并发编程 异步任务
C++并发编程 异步任务 异步任务 std::async (1) std::async 会返回一个 std::future 对象, 这个对象持有最终计算出来的结果. 当需要这个值时, 只需要调用对象的 ...
- python学习笔记(七) 类和pygame实现打飞机游戏
python中类声明如下: class Student(object): def __init__(self, name, score): self.name = name self.score = ...