vuex用法和核心 state,getters,mutations,actions,modules

一、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的值方式:

  1. this.$store.state
  2. 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)
}

获取方式:

  1. this.$store.getters.state1
  2. mapGetters(与mapState类似)
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
  ...mapGetters([
    'state1',
    'state2',
  ])
}

3.Mutations

更改 Vuex 的 store 中的状态的 唯一方法 是提交 mutation!
mutation是通过直接改变状态(全局变量state)的方式改变state
mutation 必须同步执行

mutations修改全局状态,基本写法
  1. mutations.js – 相当于生成了修改全局变量的事件函数,触发需要事件驱动
export default {
  change1: (state,options)=>{
    state.state1 = options;
  }
}
  1. 在组件中修改state1的值 – 事件触发commit
this.$store.commit('change1','修改数据11111111111')
mutations常量写法

我们经常使用常量来替代 mutation 事件类型,如下

export const SET_STATE1= 'SET_STATE1';  //mutation-types.js

import * 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常规写法
  1. Action 函数定义
    它接受一个与 store 实例具有相同方法和属性的 context 对象,有commit方法和state属性等
export const selectPlay = function ({commit, state}, {list, index}) {
//	提交mutation
	commit( 'playList',  list)
	commit( 'currentIndex', index)
	commit( 'fullScreen',  true)
}
  1. 触发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能正常使用

  1. 在这个模块中,getter正常赋值,第一个是state对象(局部全局状态中,state指的是当前的局部state)
get_data(state){
    return state.data
}
  1. 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 === this. s t o r e . s t a t e 1 m a p G e t t e r s = = = t h i s . store.state1 mapGetters === this. store.state1mapGetters===this.store.getters.state1
mapMutations === this.$store.commit(‘SET_STATE1’,‘修改数据11111111111’)
mapActions === this.store.dispatch(‘selectPlay’)
map后面可以是对象,也可以是数组,数组里放原方法名或属性名;对象,自己定义新的方法名或属性名

理解这些,再使用vuex就没什么问题了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值