[Vue]Vuex 总结

75 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

本篇附 github 代码

github

Getter

state && getters

1、定义 store。

当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工。

“getter”(可以认为是 store 的计算属性)。

(1)state:定义数据项;

(2)getters:处理数据项;

import Vue from 'vue'
import Vuex from 'vuex'
​
Vue.use( Vuex )
​
export default new Vuex.Store( {
    state: {
        sum: 2,
        address: 'shenzhen',
    },
    getters: {
        bigSum( state ) {
            return state.sum * 10
        },
    },
    mutations: {},
    actions: {},
    modules: {},
} )

2、调用。

(1)this.$store.getters.bigSum 直接调用;

(2)computed 绑定

/**
* Monday 2022/11/14 10:41:29
* src/components/Getters.vue
*/
<template>
  <div class="getters">
    <h2>
      <span>sum:{{ this.$store.state.sum }}</span> ||
      <span>sum:{{ getStateSum }}</span> 
    </h2>
    <h2>
      <span>address:{{ this.$store.state.address }}</span> ||
      <span>address:{{ getStateAddress }}</span> 
    </h2>
    <h2>
      <span>getters: {{ this.$store.getters.bigSum }}</span> ||
      <span>getters:{{ getBigSum }}</span> 
    </h2>
  </div>
</template><script>
export default {
  name: 'Getters',
  computed: {
    getBigSum() {
      return this.$store.getters.bigSum
    },
    getStateSum() {
      return this.$store.state.sum
    },
    getStateAddress() {
      return this.$store.state.address
    },
  },
}
</script>

mutations && actions

1、state 定义数据、mutations 事件注册(大写)。

你不能直接调用一个 mutation 处理函数。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation 处理函数,你需要以相应的 type 调用 store.commit 方法:

import Vue from 'vue'
import Vuex from 'vuex'Vue.use( Vuex )
​
export default new Vuex.Store( {
    state: {
        sum: 2,
        address: 'shenzhen',
    },
    getters: {
        bigSum( state ) {
            return state.sum * 10
        },
    },
    mutations: { // 准备mutations-- 用于操作数据(state)
        Add( state, value ) {
            console.error( 'Mutations:', state, value )
            state.sum += value
        },
        Reduce( state, value ) {
            state.sum -= value
        },
    },
    actions: { // 准备 action-- 用于响应组件中的动作
        add( context, value ) {
            console.log( 'action:', context, value )
            context.commit( 'Add', value )
        },
        surplus( context, value ) {
            if ( context.state.sum % 2 ) {
                console.error( 'Surplus' )
                context.commit( 'Add', value )
            }
        },
        addAsync( context, value ) {
            setTimeout( () => {
                context.commit( 'Add', value )
            }, 500 )
        },
    },
    modules: {},
} )

2、在组件中提交 Mutation

你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。

即:(1)数组

...mapMutations(['increment'])等同于this.$store.commit('increment')

(2)对象

...mapMutations({add: 'increment' })等同于this.add()也等同于this.$store.commit('increment')

也即,辅助函数不仅可以节省写法,还帮助我们主动进行方法的提交。

mutations--store.commit

actions--store.dispatch

不用背。

import { mapMutations } from 'vuex'
​
export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
​
      // `mapMutations` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}

2、actions 定义方法-- 用来 dispatch 分发动作。

/**
* Monday 2022/11/14 13:47:36
* src/components/Actions.vue
*/
<template>
  <div class="">
    <el-select v-model="num" value="">
      <el-option value="1">1</el-option>
      <el-option value="2">2</el-option>
      <el-option value="3">3</el-option>
    </el-select>
    <el-button @click="increment" type="success" round>increment</el-button>
    <el-button @click="decrement" type="primary" icon="el-icon-edit">decrement</el-button>
    <el-button @click="surplus" type="primary" icon="el-icon-share">surplus</el-button>
    <el-button @click="addAsync" type="primary" icon="el-icon-delete">addAsync</el-button>
    <el-button type="primary" icon="el-icon-search"></el-button>
    <el-button type="primary"><i class="el-icon-upload el-icon--right"></i></el-button>
  </div>
</template><script>
export default {
  name: 'Actions',
  data() {
    return {
      num: 9,
    }
  },
  methods: {
    increment() {
      console.log( 'increment' )
      this.$store.dispatch( 'add', this.num )
    },
    decrement() {
      console.log( 'decrement' )
      this.$store.commit( 'Reduce', this.num )
    },
    surplus() {
      this.$store.dispatch( 'surplus', this.num )
    },
    addAsync() {
      this.$store.dispatch( 'addAsync', this.num )
    },
  },
}
</script><style lang="scss" scoped>
el-button {
  margin-left: 10px;
}
</style>