一、vuex是干什么的
当你的项目中,需要共享应用中组件状态的时候,就会用到vuex,称之为状态管理器。简单来说,就是公共变量,意在全局把控公共数据,共享全局数据。
小型项目,可以用localStorage存储公共变量,共享数据。
相关文章(vuex具体使用方法):vuex的初始化
二、核心
首先创建store实例,并注册:
//创建store实例
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
...options })
//在入口文件添加store
import store from "./store"
new Vue({
el: '#app',router,store,render: h => h(App)
})
options重要选项:State Getters Mutations Actions Modules
1.state
Vuex 使用单一状态树——用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。
state是全局变量组成的全局对象,通过this.$store.state
可以获取这个对象。
获取state的值方式:
this.$store.state
- mapState语法糖,即辅助函数
写法( 一般获取公共变量都放在computed中获取,使用 mapState 辅助函数生成计算属性 )
computed:{
...mapState({
state1: 'state1', // 第一种写法state2: (state) => state.state2, // 第二种写法})//或者...mapState(['state1','state2'])
},
state可以直接修改值,比如this.$store.state.state1 = '12ddwd'
,state值就会改变。
2.Getters
有时候我们需要从 store 中的 state 中派生出一些状态,就是需要在全局变量的基础上,获取全局变量相关的属性值
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter 接受 state 作为其第一个参数:
export const state1 = (state)=>{
return state.state1
}
export const oneTodos = (state )=> {
return state.todos.filter(todo => todo.done)
}
获取方式:
this.$store.getters.state1
- mapGetters(与mapState类似)
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中...mapGetters(['state1','state2',])
}
3.Mutations
更改 Vuex 的 store 中的状态的 唯一方法 是提交 mutation!
mutation是通过直接改变状态(全局变量state)的方式改变state
mutation 必须同步执行
mutations修改全局状态,基本写法
- mutations.js – 相当于生成了修改全局变量的事件函数,触发需要事件驱动
export default {
change1: (state,options)=>{
state.state1 = options;}
}
- 在组件中修改state1的值 – 事件触发commit
this.$store.commit('change1','修改数据11111111111')
mutations常量写法
我们经常使用常量来替代 mutation 事件类型,如下
export const SET_STATE1= 'SET_STATE1'; //mutation-types.jsimport * as types from './mutation-types';
export default {
[types.SET_STATE1](state, cid) {
state.state1= cid;},
}this.$store.commit('SET_STATE1','修改数据11111111111')
mapMutations语法糖
mutations.js方法不变
在组件中提交mutation的方法
methods: {
...mapMutations([ //如果mutations定义的常规方法'change1', // 将 `this.change1(val)` 映射为 `this.$store.commit('change1',val)`]),//二个用法多一点(常量命名)...mapMutations({
//如果mutations定义的常量方法add: 'SET_STATE1' // 将 `this.add(val)` 映射为 `this.$store.commit('SET_STATE1',val)`})
}//调用:
this.change1('修改后的值')
this.add('修改后的值')
4.Actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
Actions常规写法
- Action 函数定义
它接受一个与 store 实例具有相同方法和属性的 context 对象,有commit方法和state属性等
export const selectPlay = function ({
commit, state}, {
list, index}) {
// 提交mutationcommit( 'playList', list)commit( 'currentIndex', index)commit( 'fullScreen', true)
}
- 触发actions事件函数
Action 通过 store.dispatch 方法触发:
store.dispatch('selectPlay')
mapActions
actions函数定义不变
在组件中使用方式改变,即触发方式
import {
mapActions } from 'vuex'
export default {
// ...methods: {
//第一个用法多一点...mapActions(['selectPlay ' // 将 `this.selectPlay(amount)` 映射为 `this.$store.dispatch('selectPlay', amount)`]),...mapActions({
selectPlay : 'selectPlay' // 将 `this.add()` 映射为 `this.$store.dispatch('selectPlay')`})}
}//调用:
this.selectPlay({
list: playArr,index
})
5.Modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 为了解决这个问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state: {
... },mutations: {
... },actions: {
... },getters: {
... }
}const moduleB = {
state: {
... },mutations: {
... },actions: {
... }
}const store = new Vuex.Store({
modules: {
a: moduleA,b: moduleB}
})
注意:
modules模块中的state不能通过this.$store.state
获取,必须加上module的命名空间,比如:this.$store.moduleA.data1
但是getters和mutations
能正常使用
- 在这个模块中,getter正常赋值,第一个是state对象(局部全局状态中,state指的是当前的局部state)
get_data(state){
return state.data
}
- mutations有些不同
change_data(state,options){
//在这里获取局部state中的data变量的方法//console.log(this.getters.get_data)//console.log(this.state.module_1.data)//这里this.$store不存在//修改全局状态的方法state.data = options; //第一种,常见,直接替代赋值this.state.module_1.data = options;//第二种,与第一种类似,改变局部state的赋值//第三种,修改,没有新的赋值的属性,依然存在,且值不变// let add = this.getters.get_data;for (let key in add) {
if (options[key]!==undefined) {
add[key] = options[key]}}
}
三、总结
- state中的状态数据,只能通过mutation来修改
- getters是来获取state中的数据,只读
- actions是处理mutation的
- modules是来分模块处理全局状态的
mapState
mapGetters
是来获取全局变量的,作为计算属性处理
mapMutations
mapActions
相当于事件处理函数,放在methods中,等待触发
mapState
mapGetters
mapMutations
mapActions
后面可以是对象,也可以是数组,数组里放原方法名或属性名;对象,自己定义新的方法名或属性名
理解这些,再使用vuex就没什么问题了!