vuex
核心概念
状态管理有5个核心:state
、getter
、mutation
、action
、module
。
-
state
Vuex
使用单一状态树,用一个对象就包含了全部的应用层级状态。它便作为一个“唯一数据源”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。- 单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
- 不可直接对
state
进行更改,需要通过Mutation
方法来更改。 - 由于
Vuex
的状态存储是响应式的,从store
实例中读取状态最简单的方法就是在计算属性中返回某个状态。
-
getter
-
从 Vue 3.0 开始,getter 的结果不再像计算属性一样会被缓存起来。
-
Vuex
允许我们在store
中定义“getter”
(可以认为是store
的计算属性),对state
的加工,是派生出来的数据。 可以在多组件中共享getter
函数,这样做还可以提高运行效率。 -
在
store
上注册getter
,getter
方法接受以下参数:- state, 如果在模块中定义则为模块的局部状态
- getters, 等同于
store.getters
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2gDfnEZ3-1667269505985)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20211024164029832.png)]
获取getters
-
通过属性访问,
Getter
会暴露为store.getters
对象,你可以以属性的形式访问这些值。(注意,getter
在通过属性访问时是作为Vue
的响应式系统的一部分缓存其中的。)<script> import store from '@/store/index.js'//需要引入store export default { computed: { todos() { return store.getters.doneTodos } } } </script>
-
通过
this.$store
访问。<script> export default { computed: { todos() { return this.$store.getters.doneTodos } } } </script>
-
-
Mutation
- Vuex中store数据改变的唯一方法就是mutation
mutations
里面装着改变数据的方法集合,处理数据逻辑的方法全部放在mutations
里,使数据和视图分离。- 注意:
store.commit
调用mutation
(需要在根节点注入 store)。
-
Action
-
action
类似于mutation
,不同在于: -
action 提交的是
mutation
,通过mutation
来改变state
,而不是直接变更状态。 -
action 可以包含任意异步操作。
-
-
Module
-
在
main.js
文件中引入store
。<!-- 页面路径:main.js --> import {createSSRApp} from 'vue' import store from './store' export function createApp() { const app = createSSRApp(App) app.use(store) return { app } }
-
在项目根目录下,新建
store
文件夹,并在下面新建index.js
文件,作为模块入口,引入各子模块。<!-- 页面路径:store/index.js --> import {createStore} from 'vuex' import moduleA from '@/store/modules/moduleA' import moduleB from '@/store/modules/moduleB' export default createStore({ modules: { moduleA, moduleB } })
-
子模块
moduleA
页面内容。<!-- 子模块moduleA路径:store/modules/moduleA.js --> export default { state: { text:"我是moduleA模块下state.text的值" }, getters: { }, mutations: { }, actions: { } }
-
使用场景
- Vuex的状态存储是响应式的,可跟踪每一个状态变化,一旦它改变,所有关联组件都会自动更新相对应的数据。
- 共享数据,解决了非父子组件的消息传递(将数据存放在state中)。
- 统一状态管理,减少了请求次数,有些情景可以直接从内存中的state获取数据。
使用理由
- 一个组件需要多次派发事件(比如购物车数量的加减)
- 跨组件共享数据、跨页面共享数据(比如订单状态更新)
- 需要持久化的数据(比如登陆后的用户信息)
- 多模块多页面的数据交互
与全局变量的区别
- **数据修改:**vuex不能直接改变store里面的变量,而是由统一的方法修改数据;全局变量可以任意修改。
- **变量名的引用:**vuex每个组件可以根据自己的vuex变量名引用不受影响;全局变量可能操作命名污染。
- **通信:**vuex解决了多组件之间通信的问题;全局变量跨页面数据共享。
- **应用场景:**vuex适用于多模块、业务关系复杂的中大型项目;全局变量适用于demo或者小型项目。
使用 Vuex 需要遵守的规则:
-
应用层级的状态应该集中到单个
store
对象中。 -
提交
mutation
是更改状态的唯一方法,并且这个过程是同步的。 -
异步逻辑都应该封装到
action
里面。 -
如果你的
store
文件太大,只需将action
、mutation
和getter
分割到单独的文件。对于大型应用,我们会希望把
Vuex
相关代码分割到模块中。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ex8OSq0w-1667269505989)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20211024161556300.png)]
写在最后
vue是单向数据流,子组件不能直接修改父组件的数据,而通过vuex状态管理实现:把组件的共享状态抽取出来,以一个全局单例模式管理。