Vuex的使用(vue2.0)

什么是Vuex?

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

Vuex核心概念

state

单一状态树即单一数据源,在一个项目中只使用一个store对象,来存储所有共享的状态信息。获取数据通过this.$route.state或者mapState

Getters:

加工数据,类似于计算属性。依赖的数据变化,会自动更新​。获取getter的方法:this.$store.getters​或者 mapGetters 返回的是对象,存的是计算属性,展开放到computed

mutations:

可以修改state,在mutations里定义方法修改state,方法的第一个形参是state,第二个形参是调用方法传过来的数据​ 调用mutations里的方法通过this.$store.commit或者mapMutations放到method里面

actions:

处理异步,不能直接修改数据,需要触发mutations的方法。在actions中定义方法,如果要修改数据,需要调用mutations里的方法。actions的第一个形参类似$store,在actions内使用$store.commit()调用mutations里的方法​了。调用actions的方法:this.$store.dispatch() 或者mapActions()放到method里面

module:

进行模块化。父组件中 modules:{放置子模块的属性} 子模块也是一个对象​,子模块通过$store.state.子模块.属性获取数据,一般用getters快捷访问。namespaced:​ 默认情况下,模块内部的actions,mutations和getters是注册在全局命名空间的,可以直接在全局调用​ 。namespaced可以保证内部模块的高封闭性​,在父组件的子模块中加上namespaced:true​ 在子模块调用需要加上模块的路径或者借助createNamespacedHelpers


前言

下面我们以改变页面中动漫人物的名称为例来示范如何使用vuex以及介绍一些简单的规范


使用vuex示例

安装vuex

npm i vuex --save

store/index.js

一般我们建议在项目的src路径下,建立store文件夹,用于存放所有的状态,然后引入到main.js中

import Vue from "vue";
import Vuex from "vuex";
import user from "./modules/user";
import getters from "./getters";
Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    user,
  },
  getters,
});

export default store;

main.js

引入到main.js中以后,我们之所以要在原型上挂载store,就是为了后面能在项目中直接使用this.$store来访问状态管理器中所有的变量以及方法

import Vue from "vue";
import App from "./App.vue";
import store from "./store";

Vue.config.productionTip = false;
Vue.prototype.$store = store;
new Vue({
  store,
  render: (h) => h(App),
}).$mount("#app");

store/getters.js

我们在store的文件夹下建立一个统一的getters.js文件,然后统一管理项目中所有的state的快捷入口

const getters = {
  name: (state) => state.user.name,
};

export default getters;

store/modules/user.js

我们在store文件夹下建立一个modules文件夹,用于做vuex的模块化,方便区分不同模块的状态管理;

namespaced是为了开启命名空间,防止命名冲突,一般情况我们建议开启

const state = {
  name: "下忍鸣人",
};
const mutations = {
  EditName: (state, name) => {
    state.name = name;
  },
};
const actions = {
  EditNameAsyc: ({ commit }, name) => {
    setTimeout(() => {
      commit("EditName", name);
    }, 2000);
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};

App.vue

1.在页面中使用vuex,我们一般建议使用辅助函数createNamespacedHelpers,可以较为简洁的使用vuex中的变量和方法;

2.一般我们不建议直接使用mapState来直接获取变量,推荐使用mapGetters和this.$store来获取相关变量的state;

3.注意如果不使用辅助函数createNamespacedHelpers,那么使用mapMutations和mapActions的时候需要补全命名空间路径;比如使用辅助函数的时候 ...mapMutations(["EditName"]),那么不使用的时候就要这么写, ...mapMutations(["user/EditName"])

4.使用this.$store来获取mutations的时候,需要使用commit方法来调用相关方法;使用this.$store来获取actions的时候,需要使用dispatch方法来调用相关方法

<template>
  <div>
    <div>vuex测试</div>
    <div>原型写法:{
   
   { $store.state.user.name }}</div>
    <div>mapGetters写法:{
   
   { name }}</div>
    <div>mapStates写法:{
   
   { stateName }}</div>
    <button @click="handleChangeName">标签修改姓名</button>
    <button @click="handleChangeNameHelp">辅助函数修改姓名</button>
    <button @click="handleChangeNameAsyc">标签异步改变姓名</button>
    <button @click="handleChangeNameHelpAsyc">标签异步改变姓名</button>
  </div>
</template>

<script>
import { mapGetters, createNamespacedHelpers } from "vuex";
const { mapMutations, mapState, mapActions } = createNamespacedHelpers("user");
export default {
  components: {},
  data() {
    return {};
  },
  computed: {
    ...mapGetters(["name"]),
    ...mapState({
      stateName: (state) => state.name,
    }),
  },
  created() {},
  methods: {
    ...mapActions(["EditNameAsyc"]),
    ...mapMutations(["EditName"]),
    handleChangeName() {
      this.$store.commit("user/EditName", "中忍鸣人");
    },
    handleChangeNameHelp() {
      this.EditName("上忍鸣人");
    },
    handleChangeNameAsyc() {
      this.$store.dispatch("user/EditNameAsyc", "漩涡鸣人仙人模式");
    },
    handleChangeNameHelpAsyc() {
      this.EditNameAsyc("火影鸣人");
    },
  },
};
</script>
<style lang="scss" scoped></style>

拓展

1.为什么不能在mutations里写异步代码? 

每个mutations执行完成后会对应到一个状态更改,这样devtools就可以打个快照存下来。如果mutation支持异步操作,就没有办法知道状态是如何更新的了,无法很好的进行状态的追踪,给调试带来困难

2.vuex不具备持久化的功能,所以在做持久化的时候,需要搭配缓存去判断处理

猜你喜欢

转载自blog.csdn.net/yxlyttyxlytt/article/details/131894574