使用操作(Actions)进行异步状态更改
Vuex 中的操作(Actions)是处理 store
异步逻辑的主要方式。突变必须是同步的,但如果选择的话,操作也可以是异步的。另一个区别是操作获取代表存储本身的上下文对象。这允许操作调用突变(mutations)或直接与状态(state)一起工作。一般来说,大多数开发人员都会从他们的操作(actions)中调用突变(mutations)。
这可能看起来有点令人困惑,但一般来说,将操作(actions)视为对 store
的异步支持。一旦我们看到一两个例子就会明白。
让我们看一个示例操作(action)。以下代码片段包含一个突变和一个将利用该突变的异步操作:
mutations: {
setBooks(state, books) {
state.books = books;
}
},
actions: {
loadBooks(context) {
fetch('/data/books.json')
.then(res => res.json())
.then(res => {
context.commit('setBooks', res);
});
}
},
查看 loadBooks,您可以看到它发出网络请求,完成后,它会调用前面的突变并让它存储结果数据。
调用动作(action)与突变略有不同;您可以使用调度(dispatch)来代替提交(commit)调用:
this.$store.dispatch('loadBooks');
与突变一样,操作(actions)可以将传递给操作方法的参数作为第二个参数。接下来,您将构建一个 action 的示例。
练习 9.05:使用异步逻辑的操作(actions)
在本练习中,您将构建一个需要异步逻辑才能完成的操作(action)示例。这与许多现实场景非常相似,其中应用程序所需的数据是在远程 API 上找到的。您将实现网络调用并在 Vuex 存储中使用结果。
在此示例中,您将在 public 文件夹中名为 data 的子目录下设置一个可用的 JSON 资源。 当 Vue 构建代码时,它会将 public 文件夹中的所有内容复制到应用程序,使其在运行时可用。JSON 文件包含四本书的数组。每本书都有类型(type)、标题(title)和页数(number of pages)。
要访问本练习的代码文件,请参阅 https://packt.live/3eE6KQd 。
-
虽然不是必需的,但这就是 JSON 数据的结构。随意构建您自己的:
[ { "type": "nonfiction", "title": "Truth about Cats", "pages": 200 }, { "type": "nonfiction", "title": "Truth about Dogs", "pages": 100 }, { "type": "fiction", "title": "The Cat Said Meow", "pages": 400 }, { "type": "fiction", "title": "The Last Dog", "pages": 600 } ]
-
在新 store(位于 store/index.js 的常用位置)中,设置一个 books 空数组,然后定义一个操作,该操作将使用 Fetch API 检索 JSON 内容。(您将在第 10 章 “使用 Vuex - 获取远程数据” 中看到更多使用 API 的示例,以及 Axios 库形式的更强大的 HTTP 方式。)检索数据时,然后调用一个突变(mutation)来存储结果:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { books:[] }, mutations: { setBooks(state, books) { state.books = books; } }, actions: { loadBooks(context) { fetch('/data/books.json') .then(res => res.json()) .then(res => { context.commit('setBooks', res); }); } } })
-
为了调用此操作(action),请在组件中添加调度(dispatch)调用来运行操作(actions),然后添加代码来显示 books:
<template> <div id="app"> Books <ul> <li v-for="book in $store.state.books" :key="book.title"> {{ book.title }}</li> </ul> </div> </template> <script> export default { name: 'app', created() { this.$store.dispatch('loadBooks'); } } </script>
在图 9.6 中,您可以看到异步操作(action)请求其数据的结果:

现在您已经看到了在 Vuex 存储中使用异步操作的示例。请注意,即使您的代码是同步的,您也可以使用操作(actions)。如果您不确定数据将来是否会异步,那么这通常是一个好主意。现在让我们看一下简化一些样板 Vuex 语法的好方法。