初识Vuex

157 阅读1分钟

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

vuex工作原理.png

1. Getter

getter可以对 state 中的数据进行过滤、处理。
类似是Vue中的computed计算属性,也具有缓存功能。
如果state中的数据得到了改变,那么getters中的属性的值也会发生改变,如果state的值没有发生任何变化,那么getters中的属性的值就不会发生改变。

const store = createStore({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: (state) => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

mapGetters 辅助函数

mapGetters 辅助函数是将 getter 映射到局部计算属性。

import { mapGetters } from 'vuex'

export default {
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter'
    ])
  }
}

2. Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
mutation 必须是同步函数。否则会造成数据混乱。
可以在组件中使用 this.$store.commit('xxx') 提交 mutation 。

3. Action

Action 可以包含任意异步操作。

//index.js
  mutations: {
    /* mutations通过payload来接收commit传过来的参数  */
    ADD(state, payload) {
      state.num += payload;
    }
  },
  actions: {
    /* 异步请求要放在actions方法中去写
    不要再组件里去写,不然就起不到作用 */
    addajax: function ({ commit }, data) {
      setTimeout(() => {
        /* 使用解构出来的commit方法来
        提交一个mutations方法ADD来修改
        state中的值 */
        commit('ADD', data)
      }, 500)
    }
  },
//App.vue
  methods:{
    add(){
      this.$store.dispatch('addajax',this.num)
    }
  }

4. 辅助函数 mapMutations mapActions

辅助函数通过解构的方式帮助我们获取store里的数据和方法。

<template>
  <div id="app">
    <h2>App | {{ num }}</h2>
    <button @click="PLUSNUM(2)">+</button> | 
    <button @click="MINUSNUM(2)">-</button> |
    <button @click="addajax2(5)">异步加</button>
  </div>
</template>

<script>
import { mapGetters, mapState, mapMutations, mapActions } from "vuex";
export default {
  name: "App",
  computed: {
    ...mapState(["list", "num"]),
    ...mapGetters(["getMorethan3k", "getMorethan1k"]),
  },
  methods: {
    ...mapMutations(["PLUSNUM", "MINUSNUM"]),
    // 如有函数名重了,可以利用对象的方式重新命名
   ...mapActions({addajax2:'addajax'}), 
    // ...mapActions(["addajax"]),
    
   //📌获取模块里的数据与方法
    // 数组写法第一种
    ...mapMutations("modA", ["CHANGESTR"]),
    // 数组写法第二种
    /* ...mapMutations(
      ["modA/CHANGESTR"]
      // 使用:this['modA/CHANGESTR']()
    ), */
    // 对象重命名
    // ...mapMutations('modA',{fn1:'CHANGESTR'}),

    // ...mapActions('modA',['waitCfn']),
    // ...mapActions(['modA/waitCfn']),
    ...mapActions("modA", { fnWC: "waitCfn" }),
    waitChange() {
      // this.$store.dispatch("modA/waitCfn", "lets fighting!");
      // this.waitCfn('what a nice day!')
      // this['modA/waitCfn']('picnic?')
      this.fnWC("脑袋空空...");
    },
  },
};
</script>

5. 分模块使用

image.png

image.png

//App.vue
<template>
  <div id="app">
    <h1>{{$store.state.modA.modaStr}}</h1>
    <h1>{{$store.state.modB.modbStr}}</h1>
    <h2>{{$store.getters['modA/strGetter']}}</h2>
    <button @click="changeStr">改变modaStr的值</button>
    <button @click="waitChange">异步改变modaStr的值</button>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    waitChange(){
      this.$store.dispatch('modA/waitCfn','lets fighting!')
    },
    changeStr(){
      this.$store.commit('modA/CHANGESTR','fighting!')
    },
  },
};
</script>