vuex详解

一、 简介

1.1 vuex是什么

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

1.2 使用场景

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

二、 安装

2.1 脚手架安装

在脚手架 创建项目时勾选vuex的选项系统会自动创建

2.2 npm 安装

vue默认vue3版本,vuex默认vuex4版本,vuex4只能在vue3中使用,在vue2中能使用vuex3,那么不能默认下载最新的版本

npm install vuex@3 --save

三、 配置

3.1 新建 store 文件

// src/store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
    //数据,相当于data
    state: {
      name: "张三",
      age: 12,
      count: 0,
    },
    getters: {
      name: (state) => state.name,
      age: (state) => state.age,
      count: (state) => state.count,
    },
    //里面定义方法,操作state方发
    mutations: {
      addCount(state, num) {
        state.count = state.count + num;
      },
      reduce(state) {
        state.count--;
      },
    },
    // 操作异步操作mutation
    actions: {
      asyncAdd({ commit }, num) {
        setTimeout(() => {
          commit("addCount", num);
        }, 1000);
      },
    },
  modules: {
    module1: {
      namespaced: true,
      state: {
        name: "module1",
        age: 12,
      },
      getters: {
        name: (state) => state.name,
        age: (state) => state.age,
      },
      mutations: {
        changeName(state, name) {
          state.name = name;
        },
      },
      actions: {
        asyncChangeName({ commit }, name) {
          setTimeout(() => {
            commit("changeName", name);
          }, 1000);
        },
      },
    },
  },
});

3.2 在 main.js 中引入 store

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

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app');

四、 核心概念

4.1 State

4.1.1 作用

提供唯一的公共数据源,所有共享的数据统一放到storestate进行储存,类似于data

4.1.2 使用方式

  1. 通过$store.state.xx调用
  2. 使用mapState函数,从vuex按需导入
<template>
  <div>
    <p>{{ $store.state.name }} - {{ age }} - {{ count }}p>
  div>
template>

<script>
import { mapState } from "vuex";

export default {
  name: "AT",
  data() {
  	return {};
  },
  computed:{
    ...mapState(['age']),
    count(){
      return this.$store.state.count;
    }
  },
  methods: {},
};
script>

4.2 Getter

4.2.1 作用

类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据。

4.2.2 使用方式

  1. 使用mapGetters函数,从vuex按需导入
<template>
  <div>
    <p>{{ name }}p>
  div>
template>

<script>
import { mapGetters } from "vuex";

export default {
  name: "AT",
  data() {
    return {};
  },
  computed: {
    ...mapGetters(["name"]),
  },
  methods: {},
};
script>

4.3 Mutation

4.3.1 作用

更改 Vuexstore 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。

4.3.2 使用方式

  1. 使用commit触发Mutation操作
  2. 使用mapMutations函数,从vuex按需导入
<template>
  <div>
    <p>{{ $store.state.count }}p>
    <button @click="addCount1">addCount1button> | <button @click="reduce1">reduce1button><br/>
    <button @click="addCount2">addCount2button> | <button @click="reduce2">reduce2button>
  div>
template>

<script>
import { mapMutations } from "vuex";

export default {
  name: "AT",
  data() {
    return {}
  },
  methods: {
    ...mapMutations(['addCount', 'reduce']),
    addCount1() {
      this.$store.commit('addCount', 10);
    },
    reduce1(){
      this.$store.commit('reduce');
    },
    addCount2() {
      this.addCount(10);
    },
    reduce2(){
      this.reduce();
    }
  },
};
script>

4.4 Action

4.4.1 作用

Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action

原因:为了方便devtools打个快照存下来,方便管理维护。所以说这个只是规范,而不是逻辑的不允许,只是为了让这个工具能够追踪数据变化而已

4.4.2 使用方式

  1. 直接使用dispatch触发Action函数
  2. 使用mapActions函数,从vuex按需导入
<template>
  <div>
    <p>{{ $store.state.count }}p>
    <button @click="addCount1">addCount1button><br />
    <button @click="addCount2">addCount2button>
  div>
template>

<script>
import { mapActions } from "vuex";

export default {
  name: "AT",
  data() {
    return {};
  },
  methods: {
    ...mapActions(["asyncAdd"]),
    addCount1() {
      this.$store.dispatch("asyncAdd", 10);
    },
    addCount2() {
      this.asyncAdd(10);
    },
  },
};
script>

4.5 Module

4.5.1 作用

当遇见大型项目时,数据量大,store就会显得很臃肿。为了解决此问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的 statemutationactiongetter、甚至是嵌套子模块

4.5.2 使用

默认情况下,模块内部的actionmutation仍然是注册在全局命名空间的,这样使得多个模块能够对同一个actionmutation作出响应。

如果希望你的模块具有更高的封装度复用性,你可以通过添加namespaced: true的方式使其成为带命名空间的模块。当模块被注册后,它的所有stategettersmutationsactions都会自动根据模块注册的路径调整命名。

<template>
  <div>
    <p>{{ name }}p>
    <p>{{ age }}p>
    <p><button @click="changeName('lalal')">changeNamebutton>p>
    <p>
      <button @click="asyncChangeName('lalalalalal')">asyncChangeNamebutton>
    p>
  div>
template>

<script>
import { createNamespacedHelpers } from "vuex";

const { mapState, mapGetters, mapMutations, mapActions } =
  createNamespacedHelpers("module1");

export default {
  name: "AT",
  data() {
    return {};
  },
  computed: {
    ...mapState(["name"]),
    ...mapGetters(["age"]),
  },
  methods: {
    ...mapMutations(["changeName"]),
    ...mapActions(["asyncChangeName"]),
  },
};
script>

参考

  • Vuex详解,一文彻底搞懂Vuex

你可能感兴趣的:(vue.js,javascript,前端)