Vuex的理解与使用

111 阅读3分钟

什么是Vuex

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

其实就是一个为Vue.js设计的数据仓库,就是把各个组件公用的数据放到一个仓库里面进行统一的管理,这样既使得非父子组件间的数据共享变得简单明了,也让程序变得更加可维护(将数据抽离了出来),而且只要仓库里面的数据发生了变化,在其他组件里面数据被引用的地方也会自动更新。

应用场景

如果你的项目里有很多页面(组件/视图),页面之间存在多级的嵌套关系,此时,这些页面假如都需要共享一个状态的时候,此时就会产生以下两个难以解决的问题:

  • 多个视图依赖同一个状态
  • 来自不同视图的行为需要变更同一个状态

Vuex可以将组件的共享状态抽取出来,以一个全局单例模式管理。此时任何组件都可以直接访问到这个状态,或者当状态发生改变时,所有的组件都获得更新。

使用时机

  • 这个问题因人而异,如果你不需要开发大型的单页应用,此时你完全没有必要使用Vuex
  • 如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

Vuex的流程

image.png

store的使用

“store” 基本上就是一个容器,它包含着应用中大部分的状态 ( state )。

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  • 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得可以方便地跟踪每一个状态的变化。

  1. 在src路径下创建store文件夹,然后创建index.js文件,文件内容如下:
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    // 定义一个name,以供全局使用
    name: '张三',
    // 定义一个number,以供全局使用
    number: 0,
    // 定义一个list,以供全局使用
    list: [
      { id: 1, name: '111' },
      { id: 2, name: '222' },
      { id: 3, name: '333' },
    ],
  },
});

export default store;

  1. 添加到vue实例上
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // 引入我们前面导出的store对象

Vue.config.productionTip = false;

new Vue({
  el: '#app',
  router,
  store, // 把store对象添加到vue实例上
  components: { App },
  template: '<App/>',
});
  1. App.vue上的使用
<template>
  <div></div>
</template>

<script>
export default {
  mounted() {
    // 使用this.$store.state.XXX可以直接访问到仓库中的状态
    console.log(this.$store.state.name);
  },
};
</script>

State

存数据的地方,所有的数据都要存在state里面。这样理解起来就简单多了

Getter

可以认为是 store 的计算属性

Mutations

唯一能够修改数据的方法就是提交mutation,里面存的就是一些操作数据的方法,且必须为同步函数。

Actions

修改state的时候有异步操作,vuex作者不希望你将异步操作放在Mutations中,所以就给你设置了一个区域,让你放异步操作,这就是Actions。

Module

拆分项目时,如果将getters/actions/mutations等属性拆分到不同的文件中,采用的是按属性的方式去拆分。

功能拆分的话,就是 Module(模块) 。将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

展开运算符和辅助函数

每次都写this.$store.XXX让你感到厌烦,可以使用下面这些辅助函数配合展开运算符代替常用属性。 mapState mapGetters mapMutations mapActions

<script>
import { mapState, mapGetters, mapMutations,mapActions} from 'vuex';
export default {
  mounted() {
    console.log(this.name);
    console.log(this.getMessage);
    this.setNumberIsWhat({ number: 999 });
  },
  computed: {
    ...mapState(['name']),
    ...mapGetters(['getMessage']),
  },
  methods: {
    // 注意,mapMutations是解构到methods里面的,而不是计算属性了
    ...mapMutations(['setNumberIsWhat']),
//    ...mapActions(['setNum']), // 就像这样,解构到methods中
  },
//   async mounted() {
//    await this.setNum({ number: 123 }); // 直接这样调用即可
//  },
};
</script>

参考文章:
juejin.cn/post/708710… juejin.cn/post/692846…