vuex
Vuex
vuex概述
vuex是一个vue
的状态管理工具,所谓的状态就是数据,它可以帮助我们管理vue
通用的数据(多组件共享的数据)
vuex的常用场景
- 某个数据在多个组件来使用,比如个人信息
- 多个组件共同维护一份数据,比如购物车数据
vuex的优势
- 数据集中化管理,共同维护一份数据
- 数据响应式变化
- 操作简洁,vuex提供了一些辅助函数
vuex使用步骤
1 | graph LR |
安装vuex
1 | npm i vuex@3 |
新建vuex模块文件
新建src/store/index.js
专门存放vuex
1 | import Vue from 'vue' |
创建仓库
1 | Vue.use(Vuex) |
main.js导入挂载
在main.js
中导入仓库,挂载到Vue
实例上
1 | import Vue from 'vue' |
获取仓库
1 | //其他组件中均可获取仓库对象 |
注意:后续可以在利用vueCli
创建项目时,勾选vuex
选项,其会自动完成上述步骤
state
提供数据
State
提供唯一的公共数据源,所有共享的数据都要统一放到Store
中的State
中存储,在State
对象中可以添加我们要共享的数据
1 | cosnt store = new Vuex.Store({ |
获取数据
方案一:通过store直接访问
1 | //模板中获取数据 |
方案二:通过辅助函数
利用mapState
辅助函数,帮助我们把store
中的数据自动映射到组件的计算属性中
1 | graph LR |
导入mapState
1 | import{ mapState } from 'Vuex' |
数组方式引入state
1 | mapState(['数据名']) |
展开运算符映射
1 | computed:{ |
其他组件访问数据
1 | {{ 数据名 }} |
mutations
mutations基本用法
vuex
同样遵循单向数据流,组件中不能直接修改仓库中的数据,因为一旦项目规模比较大,后续数据发生变化,无法清晰确定是哪个组件操作引起的数据变化
state
数据的修改只能通过mutations
的操作流程来进行
语法
- 定义
mutations
对象,对象中存放修改state
的方法
1 | const store = new Vuex.Store({ |
- 组件中提交调用
mutations
1 | this.$store.commit("修改逻辑函数名") |
mutations传参
提交mutations
时是可以传递参数的this.$store.commit("逻辑函数名",参数)
注意:mutations
参数有且只能有一个,如果需要多个参数,则包装成一个对象进行传递
辅助函数mapMutations
mapMutations
是把位于mutations
中的方法提取出来,映射到组件methods
中
语法
1 | import {mapMutations} from 'vuex' |
在使用的地方直接使用:{{ 逻辑函数名 }}
actions
actions
用于处理异步操作,比如指定一秒钟之后,修改某个数据的值,而mutations
必须是同步的
实例:一秒钟之后,修改state
的count
为666
1 | //提供action方法 |
组件页面中的调用
1 | this.$store.dispatch('setAsyncCount',666) |
辅助函数mapActions
辅助函数mapActions
是把位于actions
中的方法提取出来,映射到methods
中
1 | methods:{ |
getters
定义getters
除了state
之外,有时我们需要从state
中派生出一些状态,这些状态是依赖state
的,此时就会用到getters
实例:state中定义了一个list,是1-10的数组,现在需求为在组件中,显示所有大于5的数据
1 | state:{ |
1 | getters:{ |
访问getters
方法1:通过store访问getters
1 | {{ $store.getters.filterList }} |
方法2:通过辅助函数mapGetters映射
1 | computed:{ |
获取数据:{{ filterList }}
modules
基本语法
由于vuex
使用单一状态树,应用的所有状态(数据)会集中到一个比较大的对象,当应用变得非常复杂时,store
对象就会变得相当臃肿,vuex
就会变得越来越难以维护,此时就需要进行模块拆分,根据具体项目的业务,对状态按模块进行划分
实例语法:将用户信息模块单独划分
新建文件src/store/module/user.js
1 | const state = { |
在src/stote/index.js
中导入对应模块
1 | import user from './moudle/user' |
访问模块中的state
尽管已经分模块了,但其实子模块的状态,还是会挂到根级别的state
中,属性名就是模块名
方法1:通过store来访问
1 | $store.state.模块名.数据名 |
方法2:通过mapState来映射
子模块的映射需要开启命名空间,即在子模块导出的地方添加一项配置1
2
3
4
5
6
7export default{
namespaced: true,
state,
mutations,
actions,
getters
}
子模块的映射语法1
mapState("模块名",["数据名"])
访问模块中的getters
直接通过模块名访问
1 | $store.getters["模块名/数据名"] |
通过mapGetters映射
同样需要开启命名空间
子模块的映射语法
1 | mapGetters("模块名",["数据名"]) |
调用模块中的mutations
注意:默认模块中的mutations
和actions
会被挂载到全局,需要开启命名空间,才会挂载到子模块
通过store调用子模块mutation
1 | $store.commit('模块名/mutation函数名',额外参数) |
通过mapMutations进行映射
1 | mapMutations("模块名",["mutation函数名“]) |
调用子模块中的action
同样需要预先开启命名空间
通过store调用子模块中的action
1 | $store.dispatch("模块名/action里面的函数名",额外参数) |
通过mapActions映射
子模块的映射语法
1 | mapActions("模块名",["action函数名"]) |