内容简介:在上一篇教程中,我们在在Vuex 在跟踪应用程序中的数据状态方面也非常有用。如果你使用了 Vue 开发工具,就可以查看每个模块包含的数据以及如何访问它。
在上一篇教程中,我们在 resources/assets/js/api/cafe.js
文件中通过 JavaScript 的 Axios 库构建了一些调用 Laravel 后端 API 路由的方法。在这一篇教程中我们需要将从 API 接口获取的数据保存下来以便在单页面应用中使用,而这正是 Vuex 模块可以大展拳脚的地方。
在 Vuex 文档 中将 Vuex 定位成专为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。听上去有点抽象,翻译过来就是可以在多个组件和页面中使用的单点数据。为什么我们需要这个?因为随着构建的应用越来越大,单页面也会变得越来越复杂,在多个地方使用数据会非常麻烦。例如,假设你有一份登录到应用的用户数据,有了 Vuex 模块之后,你无需通过用户名将用户作为参数传递到不同的组件,只需将其保存到 Vuex 模块中,然后在任何地方都可以访问这个模块来获取数据。
Vuex 在跟踪应用程序中的数据状态方面也非常有用。如果你使用了 Vue 开发工具,就可以查看每个模块包含的数据以及如何访问它。
Vuex 在一开始有点难以理解,因为这是一种全新的保存数据的方式,好在 Vuex 官方文档 非常详尽,你可以通过它们深入学习。不是所有的应用都需要 Vuex 来存储数据,但是如果你在构建一个大型的单页面应用,并且需要以更优雅地方式来处理数据,那么 Vuex 是一个不错的选择。
第一步:配置 resources/assets/js/store.js
我们之前已经创建过一个初始化的 store.js
文件,现在需要打开这个文件,并添加一些代码来实现一个初始化的数据存储器。
首先,需要在 store.js
顶部导入 Vue 和 Vuex:
/** * Import Vue and Vuex */ import Vue from 'vue' import Vuex from 'vuex'
接下来,要告知 Vue 使用 Vuex 作为数据存储器,这将会扩展 Vue 实例具备使用 Vuex 数据存储器所需要的方法。将下面这行代码放到导入 Vue 和 Vuex 之后的地方:
/** * Initializes Vuex on Vue. */ Vue.use( Vuex )
最后,我们将会从 store.js
文件导出一个新的 Vuex 数据存储器。这样我们就可以将其应用到 Vue 实例并让所有模块在各个组件和路由中都可以访问。将下面这段代码放到 store.js
末尾:
/** * Export the data store. */ export default new Vuex.Store({ modules: { } });
这样我们就有了一个最基本的数据存储器配置,我们可以在其基础上轻松实现模块扩展。
第二步:安装 es6-promise 支持 IE 数据存储
上述配置在 IE 11 下不能正常工作,因为 IE 11 不支持 promise,需要通过 NPM 安装 es6-promise
:
npm install es6-promise --save-dev
然后在 resources/assets/js/store.js
文件顶部加入如下这段代码:
/** * Adds the promise polyfill for IE 11 */ require('es6-promise').polyfill();
最终版本的 store.js
文件内容如下:
/* |------------------------------------------------------------------------------- | VUEX store.js |------------------------------------------------------------------------------- | Builds the data store from all of the modules for the Roast app. */ /** * Adds the promise polyfill for IE 11 */ require('es6-promise').polyfill(); /** * Import Vue and Vuex */ import Vue from 'vue' import Vuex from 'vuex' /** * Initializes Vuex on Vue. */ Vue.use( Vuex ) /** * Export our data store. */ export default new Vuex.Store({ modules: { } });
第三步:新增数据存储器到 Vue 实例
现在数据存储器已经构建好了,需要将其添加到 Vue 中,Vue 实例位于 resources/assets/js/app.js
,打开该文件,在
import router from './routes.js'`)
之后添加如下这行代码:
import store from './store.js'
这将会引入我们上几步创建的数据存储器,接下来,我们需要通过数据存储器来扩展 Vue 实例:
new Vue({ router, store }).$mount('#app');
现在我们就可以在应用中使用整个 Vue 全家桶了!下面我们将新增一些模块并使其可以正常工作。
第四步:新增 Vuex 模块 cafes.js
首先需要在 resources/assets/js/modules
目录下创建一个名为 cafes.js
的文件,我们将在这个文件中管理所有的咖啡店数据,然后在整个应用中使用这些数据。从这里,也可以看到单页面应用的优点:一次加载页面,将数据存储到 Vuex 模块,到处使用,只有在需要重新加载页面时才重新加载。
现在 cafes.js
文件还是空的,下一步就来配置这个文件。
第五步:配置 Vuex 模块的 state 属性
在 resources/assets/js/modules/cafes.js
文件中,首先从 api
目录下导入咖啡店相关 API,我们将使用其中的 API 请求方法来加载数据:
/* |------------------------------------------------------------------------------- | VUEX modules/cafes.js |------------------------------------------------------------------------------- | The Vuex data store for the cafes */ import CafeAPI from '../api/cafe.js';
现在我们将会导出一个常量作为咖啡店模块,在导入 CafeAPI
的下面添加如下这段代码:
export const cafes = { }
这就是我们要添加到数据存储器的模块,稍后我们会将其导入到数据存储器。
接下来,我们需要设置上述 Vuex 模块的四个属性( state 、 actions 、 mutations 、 getters )。
首先,添加一个空的 state
对象:
export const cafes = { state: { } }
该状态是所有我们想要跟踪数据的状态,在 cafes
模块中有两个需要跟踪的数据:咖啡店数组,以及存储单个咖啡店的对象。分别对应返回所有咖啡店和单个咖啡店的 API。我们会这样初始化这两个数据:
export const cafes = { state: { cafes: [], cafe: {} } }
根据经验,我们经常遇到的一个问题是显示加载状态。在单页面应用中,加载状态至关重要。HTML/CSS 和其他页面功能通常会在向等待数据加载的用户提供不良UX的数据之前加载。对于我们在状态中跟踪的每个数据,我会为跟踪加载状态的数据状态添加相应的变量。这样我就可以读取这个变量来确定是否显示加载状态。 随着 Vue 被激活,数据被加载后,这个变量会更新,使用该变量的组件也会更新,并相应地显示到页面。相应的状态变量定义如下:
export const cafes = { state: { cafes: [], cafesLoadStatus: 0, cafe: {}, cafeLoadStatus: 0 }, }
我通常定义状态码如下:
status = 0 status = 1 status = 2 status = 3
这样我们就可以基于数据加载状态在需要的时候相应的提示信息。
第六步:配置 Vuex 模块的 actions 属性
actions
在模块中用于被调用来修改状态。在本教程中,我们会调用一个 action 用于发起 API 请求并提交 mutations
。 mutations
我们会在下一步中实现。
在 actions
对象中我们可以添加方法来加载所有咖啡店和单个咖啡店信息:
export const cafes = { state: { cafes: [], cafesLoadStatus: 0, cafe: {}, cafeLoadStatus: 0 }, actions: { loadCafes( { commit } ){ }, loadCafe( { commit }, data ){ } } };
上述代码 actions
部分有两个需要注意的地方:
- 每个方法都包含一个名为
commit
的析构参数,该参数通过 Vuex 传入,允许我们提交mutations
。你还可以传入其他的析构参数,要了解更多关于参数析构的细节,可以参考 lukehoban/es6features 这个 Github 项目。 -
loadCafe
动作包含了一个名为data
的第二个参数。该参数是一个对象,包含我们想要加载的咖啡店的 ID。
现在,我们来实现这两个方法:
actions: { loadCafes( { commit } ){ commit( 'setCafesLoadStatus', 1 ); CafeAPI.getCafes() .then( function( response ){ commit( 'setCafes', response.data ); commit( 'setCafesLoadStatus', 2 ); }) .catch( function(){ commit( 'setCafes', [] ); commit( 'setCafesLoadStatus', 3 ); }); }, loadCafe( { commit }, data ){ commit( 'setCafeLoadStatus', 1 ); CafeAPI.getCafe( data.id ) .then( function( response ){ commit( 'setCafe', response.data ); commit( 'setCafeLoadStatus', 2 ); }) .catch( function(){ commit( 'setCafe', {} ); commit( 'setCafeLoadStatus', 3 ); }); } },
首先需要注意的是 commit
函数,该函数用于提交一个 mutation,我们会在下一步设置 mutations
。再次重申, state
中的每个数据片段都应该有一个与之对应的 mutation。在上面两个方法中,我们都提交了所使用的状态的加载状态,接下来,调用 API 来加载想要加载的指定信息状态,这些 API 调用定义在 resources/assets/js/api/cafe.js
文件中,之后链式调用 then
和 catch
方法,前者在 API 请求成功后调用,后者在 API 请求失败后调用, response
变量会传递到这两个方法,以便获取响应数据和请求头。
第七步:配置 Vuex 模块的 mutations 属性
mutations
定义了数据的更新方式,每个模块都有 state
,每个 state
都需要对应的 mutation 来更新,完整工作流如下:
- 用户调用一个 action
- 该 action 加载/计算数据
- 该 action 提交一个 mutation
- state 被更新
- getter 将更新后的 state 返回给组件
- 组件被更新
以上工作流可以通过多种方式来实现,不过相较于 jQuery 或 vanilla JS 的实现,使用 Vuex 更加简单。
我们已经定义了 state
和 actions
,现在是时候实现 mutations
了,我们在配置 actions
时已经看到了 mutations
的调用,现在只需实现其功能代码即可:
mutations: { setCafesLoadStatus( state, status ){ }, setCafes( state, cafes ){ }, setCafeLoadStatus( state, status ){ }, setCafe( state, cafe ){ } },
所有 mutations
所做的工作都是设置 state
,所以第一个参数是 state
,这里的 state
是局部模块 state 而不是全局 state,所以我们在第六步中配置的 state
可以被访问,第二个参数是 state
更新后的数据,所以最终实现如下:
mutations: { setCafesLoadStatus( state, status ){ state.cafesLoadStatus = status; }, setCafes( state, cafes ){ state.cafes = cafes; }, setCafeLoadStatus( state, status ){ state.cafeLoadStatus = status; }, setCafe( state, cafe ){ state.cafe = cafe; } },
在每个 mutation 中,我们将局部模块的 state
数据设置为传入的更新后数据,这也正是每个 mutation 所要做的操作。接下来,我们将会配置 getters
。
第八步:配置 Vuex 模块的 getters 属性
到目前为止,我们已经有了想要跟踪的 state
数据,从 API 接口获取数据的 actions
,以及用于设置 state
的 mutations
,现在需要定义 getters
从模块中获取数据。
我们的 getters
对象需要像这样添加到 cafes
模块中:
getters: { }
接下来,需要为每一个 state
数据的获取定义一个方法:
getters: { getCafesLoadStatus( state ){ return state.cafesLoadStatus; }, getCafes( state ){ return state.cafes; }, getCafeLoadStatus( state ){ return state.cafeLoadStatus; }, getCafe( state ){ return state.cafe; } }
每个 getter 方法都会传入一个局部模块 state 作为参数并返回相应的 state 数据,这就是 getters
所做的全部工作了!现在我们可以在组件中使用所有这些数据了。
至此,我们的 Vuex 模块已经全部定义好了:
/* |------------------------------------------------------------------------------- | VUEX modules/cafes.js |------------------------------------------------------------------------------- | The Vuex data store for the cafes */ import CafeAPI from '../api/cafe.js'; export const cafes = { /** * Defines the state being monitored for the module. */ state: { cafes: [], cafesLoadStatus: 0, cafe: {}, cafeLoadStatus: 0 }, /** * Defines the actions used to retrieve the data. */ actions: { loadCafes( { commit } ){ commit( 'setCafesLoadStatus', 1 ); CafeAPI.getCafes() .then( function( response ){ commit( 'setCafes', response.data ); commit( 'setCafesLoadStatus', 2 ); }) .catch( function(){ commit( 'setCafes', [] ); commit( 'setCafesLoadStatus', 3 ); }); }, loadCafe( { commit }, data ){ commit( 'setCafeLoadStatus', 1 ); CafeAPI.getCafe( data.id ) .then( function( response ){ commit( 'setCafe', response.data ); commit( 'setCafeLoadStatus', 2 ); }) .catch( function(){ commit( 'setCafe', {} ); commit( 'setCafeLoadStatus', 3 ); }); } }, /** * Defines the mutations used */ mutations: { setCafesLoadStatus( state, status ){ state.cafesLoadStatus = status; }, setCafes( state, cafes ){ state.cafes = cafes; }, setCafeLoadStatus( state, status ){ state.cafeLoadStatus = status; }, setCafe( state, cafe ){ state.cafe = cafe; } }, /** * Defines the getters used by the module */ getters: { getCafesLoadStatus( state ){ return state.cafesLoadStatus; }, getCafes( state ){ return state.cafes; }, getCafeLoadStatus( state ){ return state.cafeLoadStatus; }, getCafe( state ){ return state.cafe; } } };
第九步:将 Vuex 模块添加到数据存储器
最后,我们还要告诉 Vuex 数据存储器使用 cafes
模块,打开 resources/assets/js/store.js
文件,紧随
Vue.use( Vuex )
之后添加如下这段代码:
/** * Imports all of the modules used in the application to build the data store. */ import { cafes } from './modules/cafes.js'
并且修改默认导出数据存储器代码如下:
export default new Vuex.Store({ modules: { cafes } });
小结
在这篇教程中,我们创建了一个 Vuex 存储器并为咖啡店配置了一个 Vuex 模块。要想看到对应的效果,编译前端资源后( npm run dev
),可以在开发环境访问 http://roast.test
并打开开发者工具,切换到 Vue 标签页,在 Vuex 部分就可以看到 state
和 getters
属性:
下一篇教程中我们演示如何在 Vue 组件中使用 Vuex 模块。
项目源码位于 Github 上: nonfu/roastapp 。
以上所述就是小编给大家介绍的《基于 Laravel + Vue 构建 API 驱动的 LBS 应用系列教程(九) —— 构建 Vuex 模块》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Java并发编程实战笔记3:基础构建模块
- IDEA下Gradle多模块(项目)的构建
- Gradle自动实现Android组件化模块构建
- 【译】JS模块的构建以及对应的打包工具
- IIS Raid-使用本地模块构建的IIS后门
- android – Dagger 2.2组件构建器模块方法已弃用
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The C Programming Language
Brian W. Kernighan、Dennis M. Ritchie / Prentice Hall / 1988-4-1 / USD 67.00
Presents a complete guide to ANSI standard C language programming. Written by the developers of C, this new version helps readers keep up with the finalized ANSI standard for C while showing how to ta......一起来看看 《The C Programming Language》 这本书的介绍吧!