一.什么是状态管理
实际截图
image.png二.VueX状态管理图
image.png三.Vuex的安装
1. 使用vuex,首先第一步需要安装vuex:
-- 我这里使用的是vuex4.x,安装的时候需要添加 next 指定版本;
安装命令: npm install vuex@next
四.Vue2.0 创建store
1. 每一个Vuex应用的核心就是store(仓库):
-- store本质上是一个容器,它包含着你的应用中大部分的状态(state);
2. Vuex和单纯的全局对象有什么区别呢?
-- 第一:Vuex的状态存储是响应式的,当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会被更新;
-- 第二:你不能直接改变store中的状态,改变store中的状态的唯一途径就显示提交 (commit) mutation;
-- 这样使得我们可以方便的跟踪每一个状态的变化,从而让我们能够通过一些工具帮助我们更好的管理应用的状态;
3. 使用步骤:
-- 创建Store对象;
-- 在app中通过插件安装;
实际创建流程如下:
image.png四.一 如何在组件中去获取VueX中的state对象中的counter:
image.png四.二.点击页面的按钮实现 + 1,-1操作,不推荐做法:
image.pngPS: 上面这种是不推荐的做法,可以看他的生态图
四.三.那么如果你想修改state中的counter数据该怎么做呢?
image.png四.四.使用计算属性computed 和直接去获取store中的state数据
image.png这种可以吗? 这种是可以的,但是你要是store的state里面数据很多,都需要获取,或者你当前页面也定义了很多计算属性,那么这种的话就不是太好维护了,下面就会使用到VueX中的mapState这个辅助函数来使用了
四.五.mapState 辅助函数--数组的写法一:
语法: ...mapState([" 这个地方绑定的是你需要从Vuex中的state里面要获取的数据的key "]),例如: ...mapState([' name ',' age ','height'....]),mapSate前面一定要加... 这个是固定语法
image.png
四.六.mapState 辅助函数--对象的写法二:
mapState辅助函数对象的写法,固定格式: ...mapState({ 自定义页面绑定变量: 函数 })
image.png
五.一 在setup中去获取Vuex 中的state对象中的数据基本流程
image.png以上是在setup中获取Vuex 中的数据基本操作流程,
五.二 但是如果要获取的数据要多了,那种写的话也是特别繁琐,那该怎么办呢?
image.png五.三 如何在setup函数中使用mapState呢?
我当时想到的方法就是直接像Vue2.0的获取方式,但是那种不行:
实际截图:
image.png五.四 自己想到的一个办法:
image.png具体代码如下:
<template>
<div>
<h2>在setup中使用store:</h2>
<!-- 1.在Vue3.0-setup中使用mapState辅助函数获取Vuex中的state数据 -->
<h2>{{ name }}</h2>
<h2>{{ age }}</h2>
<h2>{{ height }}</h2>
</div>
</template>
<script>
import { mapState, useStore } from "vuex";
import { computed } from "vue";
export default {
setup() {
// 1.
const store = useStore();
// 2.
const storeStateFns = mapState([ "name", "age", "height"])
console.log(storeStateFns); // 这里获取到的是一个对象
const storeState = {};
// 3. Object.keys:获取对象的所有的key
Object.keys(storeStateFns).forEach((fnKey) => {
const fn = storeStateFns[fnKey].bind({ $store: store });
storeState[fnKey] = computed(fn);
});
return {
...storeState,
};
},
};
// PS: 其实使用辅助函数的话就比Vue2.0 多一个步骤
</script>
<style>
</style>
五.五. 如果我在多个页面使用mapState 那么上面那段代码一直写?
下面我来做一个mapState 辅助函数的封装
import { computed } from "vue";
import { mapState, useStore } from "vuex";
export function useState(mapper) {
const store = useStore(); // 拿到vuex的store对象
// const storeStateFns = mapState(["counter", "name", "age", "height"]); // mapState中的数据是需要别人传进来的,这里不能写死
const storeStateFns = mapState(mapper);
// 对数据进行转换
const storeState = {};
Object.keys(storeStateFns).forEach((fnKey) => {
const fn = storeStateFns[fnKey].bind({ $store: store }); // $store: store 把上面定义的获取的Vuex中的store绑定到$store上,bind返回一个新的函数,this指向问题
storeState[fnKey] = computed(fn); // 使用computed 对每个函数进行计算以后赋值给storeState[fnKey],
});
return storeState // 返回整个对象
}
实际截图: --- 这个是数组的写法:
image.png实际截图: --- 这个是对象的写法:
image.png六.getters的基本使用
某些属性我们可能需要经过变化后来使用,比如说我想计算Vuex中的书籍的数量,这个时候可以使用getters
六.一.在页面使用computed去计算Vuex中的state中的books的总价格
image.pngcomputed这种方式去计算是没有问题的但是如果我很多页面用到的话,这种方式也是很繁琐的
六.二. 在页面使用 getters 去计算Vuex中的state中的books的总价格
image.png六.三.getters 的第二个参数
image.png六.四. getters返回一个函数
image.png六.五. getters返回一个函数的具体使用
image.png六.六.mapGetters的辅助函数的使用
为什么要使用mapGetters的辅助函数呢? ---当你要计算的东西很多的话,使用原始的取值方式会很臃肿,入下图所示:
image.png
六.七.在computed中使用mapGetters辅助函数 -- 数组的写法
mapGetters数组写法: ...mapGetters(['xxx','xxx',.....])
image.png
六.八.在computed中使用mapGetters辅助函数 -- 对象的写法
mapGetters数组写法: ...mapGetters({ 自定义变量: 对应的getters中定义的函数名称 })
image.png
六.九, 在setup中使用mapGetters辅助函数 --setup中基础取值
这种方式是一个一个的在取值,要是数据多了 就不推荐这种写了
image.png
六.九 在setup中使用mapGetters辅助函数 --setup中高级取值
image.png六.九.一 在setup中使用mapGetters辅助函数 --setup中封装取值
image.pngimport { computed } from "vue";
import { mapGetters, useStore } from "vuex";
export function useGetters(mapper) {
const store = useStore(); // 拿到vuex的store对象
// const storeStateFns = mapState(["counter", "name", "age", "height"]); // mapGetters中的数据是需要别人传进来的,这里不能写死
const storeStateFns = mapGetters(mapper);
// 对数据进行转换
const storeState = {};
Object.keys(storeStateFns).forEach((fnKey) => {
const fn = storeStateFns[fnKey].bind({ $store: store }); // $store: store 把上面定义的获取的Vuex中的store绑定到$store上,bind返回一个新的函数,this指向问题
storeState[fnKey] = computed(fn); // 使用computed 对每个函数进行计算以后赋值给storeState[fnKey],
});
return storeState // 返回整个对象
}
六.九.二.封装mapState和mapGetters公共代码
上面mapGetters封装的代码 和 mapState封装的代码仔细看其实是一样的,那么我封装了一个既可以mapState,也可以mapGetters复用的公共代码 具体代码实现如下:
image.png
七.一 Mutations 的基本使用:
PS: 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
image.png
七.二.Mutation携带数据
image.png很多时候我们在提交mutation的时候,会携带一些数据,这个时候我们可以使用参数:
image.png
PS: 第二个参数:一般是传递一个对象过的
image.png
七.三.Mutations提交的另外的一种风格
image.png七.四 Mutation常量类型
image.png七.五 mapMutations辅助函数--- 数组的写法:
当我在mutations中书写的函数很多,不想使用this.$store.commit的方式去提交,我们也可以借助于辅助函数,帮助我们快速映射到对应的方法中:
image.png
七.六 mapMutations辅助函数--- 对象的写法:
image.png七.七 在setup中使用mapMutations辅助函数 ---数组写法
image.pngPS: 对象写法如上面一样
七.八.具体业务场景
我想在A页面发送一个请求,把请求拿到的数据放到Vuex 全局的state中的banners 中的数据中保存下来,好让其他的页面也可以拿到数据使用
image.png
八. actions的基本使用
比如: 网络请求,异步操作的数据都可以在actions中去实现
1. Action类似于mutation,不同在于:
-- Action提交的是mutation,而不是直接变更状态;
-- Action可以包含任意异步操作;
2. 这里有一个非常重要的参数context:
-- context是一个和store实例均有相同方法和属性的context对象;
-- 所以我们可以从其中获取到commit方法来提交一个mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters;
/**
* actions的基本逻辑流程:
*
* 1. Home 页面如果想使用actions的话, 你就要想办法调用actions中定义的函数,
*
* 2. actions 中定义的函数调用mutations中的数据
*
* 3. mutations 中定义的函数 去修改 state中的数据的变化,从而实现view视图的变化/渲染
*
*
* **/
八.一.actions 的基本使用
image.png八.二 actions的具体使用业务场景
PS: 需求: 当我这个接口里面的数据很多页面需要使用,那么我就把他定义在Vuex中,让他是一个全局数据
image.png
网友评论