Vue3 之 Vuex - 状态管理

Vue3 之 Vuex - 状态管理_第1张图片

目录

一、概念

1. 状态管理

2. Vuex的状态管理

3. 单一状态树 

二、Vuex 的基本使用 

1. Vuex的安装

2. 创建store

3. 在store文件夹下创建index.js

4. 在main.js中引入 

5. 组件中使用sotre

6. 效果 

三、核心概念 State

1. 直接使用

2. mapState

使用 

封装 useState.js 文件

        代码

        使用

四、核心概念 Getters

1. 基本使用

代码

使用

2. getters第二个参数

代码

使用

3. getters的返回函数

代码

使用

4. mapGetters

使用

封装 useGetters.js 文件 

        代码

        使用

五、核心概念 Mutations

1. 重要原则 

2. 基本使用

代码

使用

3. 携带数据

代码

使用

4. 常量类型

定义mutation_types.js

代码

使用

5. mapMutations

使用

封装 useMutations.js 文件

        代码

        使用 

六、核心概念 Actions 

七、核心概念 Modules 


一、概念

vue2 契合 vuex      |      vue3 契合 pinia

1. 状态管理

在开发中,应用程序需要处理各种各样的数据,这些数据需要保存在应用程序中的某一个位置,对于这些数据的管理就称之为是状态管理

  • 在Vue开发中,使用组件化的开发方式
  • 而在组件中定义data或者在setup中返回使用的数据,这些数
    据称之为state
  • 在模块template中可以使用这些数据,模块最终会被渲染成
    DOM,称之为View
  • 在模块中会产生一些行为事件,处理这些行为事件时,有可能
    会修改state,这些行为事件称之为actions 

Vue3 之 Vuex - 状态管理_第2张图片

2. Vuex的状态管理

  • 可以考虑将组件的内部状态抽离出来,以一个全局单例的方式来管理
  • 在这种模式下,组件树构成了一个巨大的 “试图View”
  • 不管在树的哪个位置,任何组件都能获取状态或者触发行为
  • 通过定义和隔离状态管理中的各个概念,并通过强制性的规则来维护视图和状态间的独立性,代码会变得更加结构化和易于维护、跟踪

Vue3 之 Vuex - 状态管理_第3张图片

3. 单一状态树 

Vuex 使用单一状态树 : 

  • 一个对象就包含了全部的应用层级的状态
  • 采用的是SSOT,Single Source of Truth,也可以翻译成单一数据源
  • 每个应用将仅仅包含一个 store 实例
    • 单状态树和模块化并不冲突,可以使用module模块

单一状态树的优势 : 

  • 如果状态信息是保存到多个Store对象中的,那么之后的管理和维护等等都会变得特别困难
  • 所以Vuex使用了单一状态树来管理应用层级的全部状态
  • 单一状态树能够让我们最直接的方式找到某个状态的片段
  • 而且在之后的维护和调试过程中,也可以非常方便的管理和维护

单一状态树的缺点 : 不够灵活

二、Vuex 的基本使用 

1. Vuex的安装

npm install vuex

2. 创建store

每一个Vuex应用的核心就是store(仓库)

store本质上是一个容器,它包含着你的应用中大部分的状态(state)

Vuex和单纯的全局对象的区别 : 

  • 第一:Vuex的状态存储是响应式的
    • 当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会被更新
  • 第二:不能直接改变store中的状态
    • 改变store中的状态的唯一途径就显示提交 (commit) mutation
    • 这样使得我们可以方便的跟踪每一个状态的变化,从而让我们能够通过一些工具帮助我们更好的管理应用的状态

3. 在store文件夹下创建index.js

// 1. 引入
import { createStore } from 'vuex';

// 2. 创建store对象
const store = createStore({
  // 3. 定义state
  state: () => ({
    // 4. 定义数据
    count: 100
  }),
  // 5. 定义mutations
  mutations: {
    // 6. 定义方法
    increment(state) {
      state.count++;
    }
  }
});

// 5. 导出
export default store;

4. 在main.js中引入 

import { createApp } from 'vue';
import App from './App.vue';
// 1. 导入
import store from './store';
// 2. 使用
createApp(App).use(store).mount('#app');

5. 组件中使用sotre



6. 效果 

Vue3 之 Vuex - 状态管理_第4张图片

三、核心概念 State

1. 直接使用




2. mapState

使用 




封装 useState.js 文件

        代码

import { useStore, mapState } from 'vuex';
import { computed } from 'vue';

export default function useState(mapper) {
  // 1. 拿到store对象
  const store = useStore();
  // 2. 使用mapState拿到对应的方法
  const stateFnsObj = mapState(mapper);
  // 4. 定一个接受对象
  const newState = {};
  // 5.遍历
  Object.keys(stateFnsObj).forEach((key) => {
    // 6. 生成绑定过的对象
    newState[key] = computed(stateFnsObj[key].bind({ $store: store }));
  });
  // 7. 返回
  return newState;
}

        使用




四、核心概念 Getters

1. 基本使用

代码

import { createStore } from 'vuex';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  // 定义getters
  getters: {
    doubleCount(state) {
      return state.count * 2;
    }
  }
});

export default store;

使用




2. getters第二个参数

getters可以接收第二个参数,用来调用其他的getters

代码

import { createStore } from 'vuex';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  getters: {
    doubleCount(state, getters) {
      // 可以调用其他的getters函数
      return state.count * 2 + getters.mathRanDom;
    },
    // 生成[5,50)的随机数
    mathRanDom() {
      return Math.floor(Math.random() * 45) + 5;
    }
  }
});

export default store;

使用




3. getters的返回函数

getters中的函数本身,可以返回一个函数,可用来接受参数

代码

import { createStore } from 'vuex';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  getters: {
    doubleCount(state, getters) {
      // 可以调用其他的getters函数
      return state.count * 2 + getters.mathRanDom;
    },
    // 生成[5,50)的随机数
    mathRanDom() {
      return Math.floor(Math.random() * 45) + 5;
    },
    countAddNum(state) {
      // 可用来接受传进来的参数
      return function (num) {
        return state.count + num;
      };
    }
  }
});

export default store;

使用




4. mapGetters

使用




封装 useGetters.js 文件 

        代码

import { useStore, mapGetters } from 'vuex';
import { computed } from 'vue';

export default function useGetters(mapper) {
  const store = useStore();
  // 1. 接受全部getters
  const gettersFn = mapGetters(mapper);
  // 2. 定义新的函数数组
  const newGetters = {};
  // 3. 遍历绑定
  Object.keys(gettersFn).forEach((key) => {
    newGetters[key] = computed(gettersFn[key].bind({ $store: store }));
  });
  // 返沪
  return newGetters;
}

        使用




五、核心概念 Mutations

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation

1. 重要原则 

 mutation 必须是同步函数

  • 因为devtool工具会记录mutation的日记
  • 每一条mutation被记录,devtools都需要捕捉到前一状态和后一状态的快照
  • 但是在mutation中执行异步操作,就无法追踪到数据的变化 

2. 基本使用

代码

import { createStore } from 'vuex';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

export default store;

使用



3. 携带数据

代码

import { createStore } from 'vuex';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    // 接受传递过来的参数
    increment(state, num) {
      state.count += num;
    }
  }
});

export default store;

使用




4. 常量类型

定义mutation_types.js

// 定义成常量类型
export const INCREMENT = 'increment';

代码

import { createStore } from 'vuex';
// 1. 导入
import { INCREMENT } from './mutation_types';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    // 2. 使用常量作为名称,使用计算属性值
    [INCREMENT](state, num) {
      state.count += num;
    }
  }
});

export default store;

使用




5. mapMutations

使用




封装 useMutations.js 文件

        代码

import { useStore, mapMutations } from 'vuex';

export default function useMutations(mapper) {
  const store = useStore();
  // 1. 接受全部函数
  const mutationFns = mapMutations(mapper);
  // 2. 定义新的函数数组
  const newMutations = {};
  // 3. 遍历绑定
  Object.keys(mutationFns).forEach((key) => {
    newMutations[key] = mutationFns[key].bind({ $store: store });
  });
  // 返回对象
  return newMutations;
}

        使用 

六、核心概念 Actions

Action类似于mutation

  • Action提交的是mutation,而不是直接变更状态
  • Action可以包含任意异步操作

参数context : 

  • context是一个和store实例均有相同方法和属性的context对象
  • 所以可以从其中获取到commit方法来提交一个mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters
  • context不是store对象

1. 基本使用

代码

import { createStore } from 'vuex';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  getters: {
    doubleCount(state, getters) {
      return state.count * 2 + getters.mathRanDom;
    },
    mathRanDom() {
      return Math.floor(Math.random() * 45) + 5;
    }
  },
  actions: {
    // 定义actions方法
    incrementAction(context) {
      // 1. 可进行接口请求
      // balabalabala~
      // 2. 通过mutation来修改state的状态
      context.commit('increment');
    }
  }
});

export default store;

使用



2. 传递参数

代码

import { createStore } from 'vuex';

const store = createStore({
  state: () => ({
    count: 100
  }),
  mutations: {
    increment(state, num = 10) {
      state.count += num;
    }
  },
  getters: {
    doubleCount(state, getters) {
      return state.count * 2 + getters.mathRanDom;
    },
    mathRanDom() {
      return Math.floor(Math.random() * 45) + 5;
    }
  },
  actions: {
    // 定义actions方法,接受参数
    incrementAction(context, num) {
      // 调用mutations方法
      context.commit('increment', num);
    }
  }
});

export default store;

使用




3. mapActions

使用




封装 useActions.js 方法

        代码

import { useStore, mapActions } from 'vuex';

export default function useActions(mapper) {
  const store = useStore();
  // 1. 接受全部的actions
  const actionsFn = mapActions(['incrementAction']);
  // 2. 定义新的actions对象
  const newActions = {};
  // 3. 遍历
  Object.keys(actionsFn).forEach((key) => {
    newActions[key] = actionsFn[key].bind({ $store: store });
  });
  return newActions;
}

        使用




4. 异步操作 

七、核心概念 Modules

你可能感兴趣的:(Vue3,前端,javascript,vuex,vue,Vuex)