Vuex的基本使用

116 阅读3分钟

State使用

// store/index.js
state: {
    buttonPermissions:{
      add:true,
      edit:false
    }
},
    
//某个页面使用
created() {
   console.log("this.$store",this.$store.state)
},

由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性 (opens new window)中返回某个状态

mapState辅助函数

``mapState 辅助函数返回的是一个对象

一个vuex属性都是写在 计算属性 中 , 但是很显然 直接下边这样写就定义不了其他的计算属性了

基本使用

computed: mapState({
    // 箭头函数可使代码更简练
    count: state => state.count,

    // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',

    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
      return state.count + this.localCount  //this.localCount当前组件的数据
 }
  1. 通过箭头函数
  2. 通过字符串
  3. 通过常规函数

页面整体使用

//页面使用
<template>
  <div>
    <h2><span>使用:</span> {{$store.state}}</h2>
    <h2><span>data中的count:</span>{{count}}</h2>
    <h2><span>辅助函数Count:</span>{{handleCount}}</h2>
    <h2><span>辅助函数countAlias:</span>{{countAlias}}</h2>
    <h2><span>辅助函数countPlusLocalState:</span>{{countPlusLocalState}}</h2>
    <h2><span>辅助函数power:</span>{{power}}</h2>
  </div>
</template>

<script>
  import {mapState } from "vuex";
export default {

  data () {
    return {
      count:this.$store.state.count,
      localCount:"局部状态"
    }
  },
    
  computed:mapState({
    // 箭头函数可使代码更简练
    handleCount: state => state.count,

    // // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',
    
    // // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
      return state.count + this.localCount
    },
    power:"buttonPermissions"
  }),
  components: {},

  methods: {
    hadnleChangeState(){
      console.log("this.$store",this.$store);
    }
  }
}
</script>


<style scoped>
</style>

当我们计算属性的名称与state的子节点 相同, 我们也可以传一个数组

 //   store/index.js
export default new Vuex.Store({
  state: {
    buttonPermissions:{
      add:true,
      edit:false
    },
    count:1
  },
})

//某页面

computed:mapState(["count","buttonPermissions"])

解构使用

因为辅助函数返回的是一个对象,所以我们就可以使用扩展运算符,这样就可以和局部的计算属性混合使用了

Getters使用

参数说明:

  • 接收 state为第一个参数
  • 接受其他 getter 作为第二个参数

基本使用 — 以及第二参数使用 — 通过返回一个方法 对getter传参

//某个页面
<template>
  <div>
    <h2><span></span>{{$store.getters}}</h2>
    <h2><span>第二参数的使用:</span>{{$store.getters.clickCount}}</h2>
    <h2><span>返回一个函数:</span>{{$store.getters.find("媒体查询响应式布局")}}</h2>
  </div>
</template>

// @/store/index.js 
state: {
    lessons:[
      { title: "媒体查询响应式布局", click: 10 },
      { title: "FLEX 弹性盒模型", click: 20 },
      { title: "MYSQL多表查询随意操作", click: 100 }
    ],
}
 
getters:{
   //基本使用
   total :state => state.lessons.reduce((pre,cur) => pre + cur.click,0),
    //第二参数使用
   clickCount:(state,getters) => "点了量为:"+getters.total
    //通过返回一个方法 对getter传参
   find:(state) => (title) => state.lessons.find(item => item.title == title)  
},

mapGetters辅助函数

//某个vue页面
<h2><span>mapGetters辅助函数</span>{{total}}</h2>
<h2><span>mapGetters辅助函数</span>{{clickCount}}</h2>
<h2><span>mapGetters辅助函数</span>{{find("MYSQL多表查询随意操作")}}</h2>
    
computed:{
  ...mapGetters(["total","clickCount","find"]);//数组方式
    
  ...mapGetters({         //对象方式
      astotal:"total",
      click:"clickCount",
      fn:"find"
    })
}

  • mapGetters 只有数组对象 的方式 进行映射到计算属性
  • 使用数组方式是为了别名

Mutations使用

更改state 唯一办法就是 使用mutaion 方式提交

Mutation参数说明:

  • 接收 state为第一个参数
  • 接收commit的第二参数

不能直接this.$store.mutation调用,需要调用store中的commit方法

commit()方法参数说明

  • commit()方法 只有两个参数

  • mutations 属字符串作为为第一参数

  • 第二参数(官方称之为载荷) 可以 传递 任意值, 一般传obj

基本使用 - 提交载荷 - 对象方式提交载荷

//某个vue页面
<h2><span>count:</span>{{$store.state.count}}</h2>
<button @click="handleClick">mutations调用</button>
<button @click="handleClickSub">载荷调用</button>
<button @click="handleClickSubObj">对象方式载荷调用</button>

methods: {
    //基本使用
   handleClick(){
     this.$store.commit("increment")
   },
   //提交载荷
   handleClickSub(){
      this.$store.commit('sub',{num:10})
   } 
   //对象方式提交载荷  handler保持不变
    handleClickSubObj(){
      this.$store.commit({type:'sub',num:10})
    }
   
}

//   @/store/index.js


state: {
    count:1,
},

//基本使用
increment(state){
   state.count++
}
//提交载荷
sub(state,data){
   state.count -= data.num
}


Mutation需遵守Vue的响应规则

  1. 提前在store中初始化所有所需属性
  2. 当需要在对象添加新属性时,应该
    • 使用Vue.set(obj,"key",123),或者
    • 使用扩展运算符 新对象 替换老对象
      • {...state.obj , newProp:123}

Mutation必须是同步的

mapMutation辅助函数

methods: {
    handleClick(){
      this.increment();
    },
    handleClickSub(){
      this.sub({num:10})
    },
    handleClickSubObj(){
      this.sub({num:10})
    },
        
  ...mapMutations([
    "increment","sub"
  ])
}

Actions使用

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态
  • Action 可以包含任意异步操作

参数说明

  • 函数接收一个与store实例有相同方法属性context 对象,但是context对象不是store实例本身
  • 所以我们可以通过context获取
    • 提交mutation
    • state
    • getters

通过dispatch()方法触发

**基本使用 - 提交载荷 - 对象方式提交载荷 **

//某个 vue 组件
<h2><span>count:</span>{{$store.state.count}}</h2>
<button @click="handleClick">基本使用</button>
<button @click="handleClickSub">提交载荷</button>

methods: {
    handleClick(){
      this.$store.dispatch("increment")
    },
    handleClickSub(){
      //提交载荷
      this.$store.dispatch("sub",{num:10})
      //对象方式提交载荷
      this.$store.dispatch({type:"sub",num:10})
}
        

//  @/store/index.js
 state: {
    count:1,
  },   
    
mutations: {
    increment(state){
      state.count++
    },
    
    sub(state,data){
      state.count -= data.num
    }

},
    
actions: {
    increment({commit}){
      setTimeout(() => {
        commit("increment")
      }, 2000);
    },
        
    sub({commit},obj){
      setTimeout(() => {
        commit("sub",obj)
      }, 1000);
    }
},

mapActions辅助函数

import { mapActions } from 'vuex'

export default {
    
  methods: {
    ...mapActions([
      'increment', 
        // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
      		// `mapActions` 也支持载荷;
      'incrementBy' 
        // 将 `this.incrementBy(amount)` 映射this.$store.dispatch('incrementBy', amount)`
    ]),
      
    ...mapActions({
      add: 'increment' 
      // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}

我们可以在使用async await 来控制action什么时候结束

Modules

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

//
this.$store.state.a // -> moduleA 的状态
this.$store.state.b // -> moduleB 的状态

总结

  1. State 作为存放 全局的状态
  2. Getters 可以视为 状态的计算属性,接收state为第一个参数,其他的getters 为第二个参数
  3. Mutations 是 用来 通过 commit()方法 直接修改 状态 State,commit()有两个参数,第一个为state,第二个是提交的载荷,一般是一个对象。 Muttaions 里边的方法必须是同步的。
  4. Actions 是通过dispatch()方法 来分发 Mutation 进而修改状态的 ,与Mutations不同的是它可以存放异步的方法,Actions方法里边的第一个参数 是接收一个 store 实例相同的对象,所以我们可以通过解构的方式获取我们想要的commit,state,getters,dsipatch 等