一、vuex介绍
(1)vuex是什么?
借鉴 了Flux、Redux、 The Elm Architecture
专为 Vue.js 设计 的状态管理模式
集中式存储和管理应用程序中所有组件的状态
Vuex 也集成到 Vue 的官方调试工具
一个 Vuex 应用的核心是 store(仓库,一个容器),store包含着你的应用中大部分的状态 (state)
(2)什么情况下我应该使用 Vuex?
- 不适用:小型简单应用,用 Vuex 是繁琐冗余的,更适合使用简单的 store 模式。
- 适用于:中大型单页应用,你可能会考虑如何把组件的共享状态抽取出来,以一个全局单例模式管理,不管在哪个组件,都能获取状态/触发行为,解决问题如下:
① 多个视图使用于同一状态:
传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力
② 不同视图需要变更同一状态:
采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝,通常会导致无法维护的代码
(3)Vuex 和单纯的全局对象有何不同?
1.Vuex 的状态存储是响应式的
当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2.你不能直接改变 store 中的状态
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation,方便我们跟踪每一个状态的变化
store : 仓库, 每一个vuex应用的核心
基本就是一个容器,包含着应用大部分的状态
里面包含五个属性: state Getter Mutation Action Module
五个属性
state
单一状态树
> 用一个对象包含了所有应用层级的状态,作为唯一的数据源
> 利于我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个应用状态的快照
Getter
Vuex允许我们再store中定义getter(可以认为是store的计算属性)。就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
你需要以相应的 type 调用 store.commit 方法
1. payload (提交载荷))
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
载荷应该是一个对象,这样可以包含多个字段
规则:
vuex中的store中的状态是响应式的,那么当我们变更状态的时候,监视状态的Vue
组件也会自动更新,这也意味着Vuex中的mutation也需要与使用Vue一样遵守一些注意事项
1. 最好提前在你的store中初始化所有所需属性
2. 当需要在对象上添加新属性时,你应该用新对象替换老对象
Mutation必须是同步函数
一条重要的原则就是要记住 mutation 必须是同步函数
为什么: 如果mutation是异步函数,那么回调函数的执行难以控制,这就导致状态的改变不可追踪
本质: 实质上任何在回调函数中进行的状态的改变都是不可追踪的
Action
1. action提交的是mutation,而不是直接变更状态
2. action可以包含任意异步操作
3. Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters
分发Action
Action 通过 store.dispatch 方法触发
Actions 支持同样的载荷方式和对象方式进行分发
Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿
所以:Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
命名空间
可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可
项目目录
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
└── modules
├── cart.js # 购物车模块
└── products.js # 产品模块