复习vue(12)Vuex

173 阅读2分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」。

组件间通信 Vuex

  • Vuex 是什么?

Vuex 是一个专门为了 vue.js 应用程序开发的状态(状态就是数据)管理模式,它采用集中式存储管理应用的状态.
相当于把组件中的数据提升到了一个全局的地方,这个地方就是 Vuex的store(仓库),由Vuex统一管理,如果某个组件需要这个数据,直接从store中获取.

如果要修改在 Vuex 中的数据,需要在定义 store 时,定义修改这个数据的方法,这些方法成为 mutation

mutation 函数的第一个参数是 state 对象,所有的数据都定义在 state 中,在 mutation 函数中通过 state 可以修改上面 state 中的数据;

  • 注意 mutation中修改数据只能使用同步的方式,不能再异步的操作中更新数据;如果有异步的就需要使用 action;

action 也是更新数据的方式, action 不同于 mutation 的是 action 可以使用异步,但是更新数据仍然需要 commit 对应的 mutation函数;

使用 Vuex 的步骤

在此之前,你需要安装 Vuex, 如果是 vue-cli, 在初始化项目时选择vuex

  1. 把需要放到 Vuex 中的数据存在state 里面
  2. 创建修改这些数据的 mutation
  3. 如果这些数据需要异步更新,则创建对应的 action, 并且在 action 中通过commit mutation 的方式更新数据
  4. 最后导出 Vuex 的 store 实例,并且为 vue 的根实例配置 store 属性, 配置store属性后,在vue 实例中可以通过this.$store 访问 store
  5. 在整个 vue 的应用中,任何地方需要使用改数据,通过 this.$store.state.属性名的方式获取数据;
  6. 如果需要更新这些数据可以通过调用this.$store.commit(mutation函数名),如果需要异步更新,需要this.$store.dispatch(action名)

代码示例:

  • store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // state 就是数据,如果数据定义在 state 中组件中如果要使用这个数据 this.$store.state.属性名 的方式获取
    num: 15
  },
  mutations: {
    // state 中的数据不能被直接修改,如果要修改这些数据,需要使用 mutation,注意 mutation 中不能使用异步更新 state
    add(state) {
      // mutation 函数的第一个参数是 state 对象,所有的数据都定义 state 中,在 mutation 函数中通过 state 可以修改 上面 state 中的数据;
      state.num++
    },
    addOne(state) {
      // mutation 函数的第一个参数是 state 对象,所有的数据都定义 state 中,在 mutation 函数中通过 state 可以修改 上面 state 中的数据;
      state.num++
    },
    addNum(state, payload) {
      // mutation 的第二个参数 payload 是在 commit mutation 时传入的参数
      state.num += payload
    }
  },
  actions: {
    // action 可以使用异步,但是更新数据仍然需要 commit 对应的 mutation
    asyncAdd(context) {
      setTimeout(() => {
        context.commit('add')
      }, 1000)
    }
  }
})


  • App.vue
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
      <h1>someNum: {{$store.state.num}}</h1>
    </div>
    <router-view/>
  </div>
</template>

<script>
import Bus from './bus'
export default {
  name: 'App',
  data () {
    return {}
  }
}
</script>

  • Home.vue
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <div>
      <button @click="add">给上面的sumNum加加</button>
      <button @click="add2">给上面的sumNum加2</button>
    </div>
  </div>
</template>

<script>

export default {
  name: 'home',
  methods: {
    add () {
      this.$store.commit('addOne') // commit mutation
      this.$store.dispatch('asyncAdd') // dispatch action
    },
    add2 () {
      this.$store.commit('addNum', 2) // 传递 payload
    }
  }
}
</script>

mapState/mapMutations/mapActions

如果使用很多个 store 中的数据和方法时通过this.$store的方式很不方便,Vuex 提供了三个对应的方法,用于批量获取多个 state, mutation, action;

示例代码:

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <div>
      <button @click="add">给上面的sumNum加加</button>
      <button @click="add2">给上面的sumNum加2</button>
      <button @click="add3">给上面的sumNum过会加加</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
export default {
  name: "home",
  methods: {
    // add () {
    //   this.$store.commit('addOne') // commit mutation
    //   this.$store.dispatch('asyncAdd') // dispatch action
    // },
    // add2 () {
    //   this.$store.commit('addNum', 2) // 传递 payload
    // }
    add() {
      this.addOne(); // 等效于 this.$store.commit('addOne')
    },
    add2() {
      this.addNum(2); // 等效于 this.$store.commit('addNum', 2)
    },
    add3() {
      this.asyncAdd2(); // 等效于 this.$store.dispatch('asyncAdd')
    },
    ...mapMutations(["addOne", "addNum"]),
    ...mapActions({
      asyncAdd2: "asyncAdd", // 重命名
    }),
    computed: {
      ...mapState(["num"]),
    },
  },
};
</script>

  • 通过 mapState,mapMutations,mapActions 方法结合展开运算符,可以把对应的数据和方法添加到 computed 和 ,methods 中的这些方法都可以通过this实例访问