Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用 集中式 存储管理应用的所有组件的状态,并以相应的规则保证状态以一种 可预测 的方式发生变化。
vuex是采用集中式管理组件依赖的共享数据的一个工具,可以解决不同组件数据共享问题。
- 修改state状态必须通过**
mutations
**
- **
mutations
**只能执行同步代码,类似ajax,定时器之类的代码不能在mutations中执行
- 执行异步代码,要通过actions,然后将数据提交给mutations才可以完成
- state的状态即共享数据可以在组件中引用
- 组件中可以调用action
初始化:
1 2 3 4 5 6 7 8 9 10 11 12
| npm i vuex --save
import Vue from 'vue' import Vuex from 'vuex' Vue.use(vuex) const store = new Vuex.Store({}) new Vue({ el: '#app', store })
|
state
- state是放置所有公共状态的属性,如果你有一个公共状态数据 , 你只需要定义在 state对象中
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
const store = new Vuex.Store({ state: { count: 0 }, computed: { count () { return this.$store.state.count } } })
|
1 2 3 4
|
<div> state的数据:{{ $store.state.count }}</div> <div> state的数据:{{ count }}</div>
|
1 2 3 4 5 6 7 8 9
| import { mapState } from 'vuex'
mapState(['count'])
computed: { ...mapState(['count']) }
|
mutations
- state数据的修改只能通过mutations,并且mutations必须是同步更新,目的是形成 数据快照
- 数据快照:一次mutation的执行,立刻得到一种视图状态,因为是立刻,所以必须是同步
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const store = new Vuex.Store({ state: { count: 0 }, mutations: { addCount (state,payload) { state.count += payload } } })
|
1 2 3 4 5
|
this.$store.commit('addCount', 10)
|
1 2 3 4 5
| import { mapMutations } from 'vuex' methods: { ...mapMutations(['addCount']) }
|
- 注意: Vuex中mutations中要求不能写异步代码,如果有异步的ajax请求,应该放置在actions中
actions
- state是存放数据的,mutations是同步更新数据,actions则负责进行异步操作
1 2 3 4 5 6 7 8 9
| actions: { getAsyncCount (context) { setTimeout(function(){ context.commit('addCount', 123) }, 1000) } }
|
1 2
| this.$store.dispatch('getAsyncCount')
|
1 2 3 4 5
| import { mapActions } from 'vuex' methods: { ...mapActions(['getAsyncCount']) }
|
getters
- 除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters
- 类似于vue计算属性
1 2 3 4 5 6 7 8 9
| state: { list: [1,2,3,4,5,6,7,8,9,10] } -------------------------------- getters: { filterList: state => state.list.filter(item => item > 5) }
|
1 2
| <div>{{ $store.getters.filterList }}</div>
|
1 2 3 4 5
| import { mapGetters } from 'vuex' computed: { ...mapGetters(['filterList']) }
|
Vuex中的模块化-Module
- 如果把所有的状态都放在state中,当项目变得越来越大的时候,Vuex会变得越来越难以维护 由此,又有了Vuex的模块化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const store = new Vuex.Store({
modules: { user: { state: { token: '12345' } }, setting: { state: { name: 'Vuex实例' } } })
|
1 2 3
| <div>用户token {{ $store.state.user.token }}</div> <div>网站名称 {{ $store.state.setting.name }}</div>
|
1 2 3 4 5 6 7 8 9
| getters: { token: state => state.user.token, name: state => state.setting.name }
computed: { ...mapGetters(['token', 'name']) }
|
命名空间 namespaced
- 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
- 刚才的user模块还是setting模块,它的 action、mutation 和 getter 其实并没有区分,都可以直接通过全局的方式调用
1 2 3 4 5 6 7 8 9 10 11
| user: { state: { token: '12345' }, mutations: { updateToken (state) { state.token = 678910 } } },
|
1 2 3 4
| methods: { ...mapMutations(['updateToken']) }
|
为了保证内部模块的高封闭性,我们可以采用namespaced来进行设置(加上一把锁)
1 2 3 4 5 6 7 8 9 10 11 12
| user: { namespaced: true, state: { token: '12345' }, mutations: { updateToken (state) { state.token = 678910 } } },
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
this.$store.dispatch('user/updateToken')
methods: { ...mapMutations(['user/updateToken']), test () { this['user/updateToken']() } }
import { mapGetters, createNamespacedHelpers } from 'vuex' const { mapMutations } = createNamespacedHelpers('user')
methods: { ...mapMutations('user',['updateToken']), }
|
其他
带命名空间的模块,获取根store,当前模块,兄弟模块中的方法
根store
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| state数据: 通过rootState参数 即:rootState.属性名 getter方法:通过rootGetters参数来获取 即:rootGetters.increNum 附:向根getters中传递参数方式:rootGetters.increNum({id:11,name:'lucy'}); 根store中getters定义接多参数: getters:{ increNum:(state)=>(obj)=>{ console.log(obj) } } 提交mutations:commit('increment',null,{root:true}); 分发actions:dispatch('incrementAction',null,{root:true}); 参数部分示例:actions:{ moduleAAction({state,commit,dispatch,getters,rootState,rootGetters}){ } }
|
当前模块
1 2 3 4 5 6 7 8
| state数据:通过state参数来获取 即:state.属性名 getter方法:通过getters参数来执行 即:getters.moduleAIncreNum(); 提交mutations:通过commit参数来执行 即:commit('moduleAMutation); 参数部分示例:actions:{ moduleAAction({state,commit,dispatch,getters,rootState,rootGetters}){ //处理逻辑 } }
|
兄弟模块中
1 2 3 4
| state数据:通过rootState参数来获取 即:rootState.moduleB.属性名 getter方法:通过getters参数来执行 即:rootGetters['moduleB/moduleBGetter'] 提交mutations:通过commit参数来执行 即:commit('moduleB/moduleBMutation',{},{root:true}); 分发actions:通过dispatch参数来执行 即:dispatch('moduleB/moduleBAction',{},{root:true});
|
将命名空间的action注册为全局action