初识vue 2.0:vuex进阶
Posted phptree
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识vue 2.0:vuex进阶相关的知识,希望对你有一定的参考价值。
主要讲三部分内容:
- vuex模块化
- vuex命名空间
- mutations和actions
模块化
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象,当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module),每个模块拥有自己的 state、mutation、action、getter。
因此,创建一个store目录,用来存储状态。
store/
|_ index.js
|_ helloModule.js
|_ gameModule.js
在index.js中导出组件,并在main.js中注册
index.js
/** * 状态注册 */ import helloState from ‘./helloModule.js‘ import gameState from ‘./gameModule.js‘ export const modules = { modules: { helloState, gameState } }
main.js
// ... import { modules } from ‘./store‘ Vue.use(Vuex) //集中状态管理 const store = new Vuex.Store(modules); new Vue({ el: ‘#app‘, store,//我在这儿 template: ‘<App/>‘, components: { App } })
命名空间
在命名空间出现之前,Module只是将状态分开,mutations或actions却没有分开。在调用的时候,如果采用一样的命名,在调用时就都会被执行。
因此大家一般将mutations或actions中的方法名抽象成常量,保存在单独的文件中,以避免命名污染。
有了命名空间之后,只要设置 namespaced: true,模块间的方法便相互独立,互不影响,在语法上,也会稍有修改。
helloModule.js
/* global module:true */ export default module = { // 开启命名空间 namespaced: true, // 定义状态 state: { msg: ‘我是Hello模块‘ }, // 获取状态 getters: { msg: (state) => (txt) => { return txt + state.msg // 接受传参 } }, // 改变状态 mutations: { // 包含异步修改状态 setMsg (state, msg) { state.msg = msg setTimeout(() => { state.msg = ‘mutations修改成功‘ // 使用commit直接调用此异步方法,能达到修改数据的目的,最终状态没办法追踪 }, 1000) }, // 不包含异步修改状态 setMsg2 (state, msg) { state.msg = msg } }, actions: { // 异步修改状态 setMsg (context, msg) { context.commit(‘setMsg2‘, msg) setTimeout(() => { context.commit(‘setMsg2‘, ‘actions修改成功‘) // 使用dispatch调用,此异步状态修改可以追踪 }, 1000) } } }
gameModule.js 略
mutations和actions
为什么说mutation只能同步,而action通过commit,可以异步执行mutation?
官网解释:
现在想象,我们正在 debug 一个 app 并且观察 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都需要捕捉到前一状态和后一状态的快照。然而,在上面的例子中 mutation 中的异步函数中的回调让这不可能完成:因为当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。
在 mutation 中混合异步调用会导致你的程序很难调试。例如,当你调用了两个包含异步回调的 mutation 来改变状态,你怎么知道什么时候回调和哪个先回调呢?这就是为什么我们要区分这两个概念。在 Vuex 中,mutation 都是同步事务。
也就是说使用commit调用mutations的方法中,包含异步修改状态的操作,也是能执行成功的;
但是在debug过程中,devtools捕捉不到异步修改的状态的快照,导致调试困难;
因此官方提供了dispatch调用actions的方法来完成异步操作。
并且可以使用dispatch返回promise对象,在组件中完成then操作。
Hello.vue
<template> <div class="hello"> <h2>{{ msg }}</h2> <button @click="answer">修改</button> <button @click="show">查看</button> </div> </template> <script> export default { name: ‘hello‘, data () { return { newMsg:"修改中" } }, computed: { msg: function () { return this.$store.state.helloState.msg } }, methods: { answer () { this.$store.dispatch(‘helloState/setMsg‘,this.newMsg); }, show () { alert(this.$store.getters[‘helloState/msg‘](‘查看内容是:‘)); } } } </script> <style> .hello{ background-color:#E1FFFF; } </style>
组件绑定的辅助函数
也就是 mapState,mapMutations,mapGetters、mapActions 这些,一般是可以看作简化语法的语法糖,有机会再详细讲讲。
使用mapState获取状态的简单实例:
修改Hello.vue
import {mapState} from ‘vuex‘; export default { // ... computed: { ...mapState ({ msg:state => state.helloState.msg }) }, }
以上是关于初识vue 2.0:vuex进阶的主要内容,如果未能解决你的问题,请参考以下文章