Vue3——Vuex状态管理

求一键三连

希望大家看完觉得有用的话点赞、关注和收藏,感谢!!!

前言

关于状态管理的两个库——vuex/pinia
pinia是更适配vue3的,并且更好用,但是现在很多公司大量的项目用的是vuex,所以还是要了解。
后面pinia一定会占据主流。pinia相当于vuex5的版本,官方推荐也在推荐pinia。学完vuex再学pinia之后会更快,因为概念是一样的。

因为vue3(composition api)是适用pinia的,所以在vue3里面使用vuex就会特别别扭,很多不适配,所以vuex是了解就好,主要是记录主要的使用,在后面项目中用到的时候再来看就行,主要是要知道有哪些用法。

所以最好的办法就是除了setup语法之外,在多写一个options api的script,这样也是OK的,然后在里面写相关的操作。
在这里插入图片描述
一共五个核心点,记住这个目录

认识状态管理(前端数据库)

在我看来这不就是前端的“数据库”吗,就是创建一个store.js来存储数据,vuex负责管理(响应式)

在这里插入图片描述

在前面学父子组件间通信的时候就提到了状态管理,因为这样传数据是很麻烦的,并且当组件多了之后管理就很不方便,还是像数据库一样把数据单独抽出来管理是最合适的,这个抽取的思想很重要。

在这里插入图片描述

在这里插入图片描述

总的来说,状态是不断变化的,因为要遵循单向数据流,所以所有的数据变化还是要放在store.js里面完成,这样才方便对状态进行管理。
在这里插入图片描述

vuex使用

在这里插入图片描述

store=仓库=数据库

Vuex基本使用

  • 安装vuex
  • 创建store
  • app.use(store)
  • tempate -> $store.state.counter

创建store

在这里插入图片描述

单向数据流,组件里无法改变数据,需要commit提交到store中进行改变。

import {
    
     createStore } from 'vuex'

const store = createStore({
    
    
  state: () => ({
    
      
    counter: 100,
    name: "coderwhy",
    level: 100,
    avatarURL: "http://xxxxxx",
    friends: [
      {
    
     id: 111, name: "why", age: 20 },
      {
    
     id: 112, name: "kobe", age: 30 },
      {
    
     id: 113, name: "james", age: 25 }
    ]
  }),

组件中使用store

在这里插入图片描述

模板中使用:

可以直接拿,但这样比较繁琐,所以还是在computed里面封装一下再使用比较好
在这里插入图片描述

options api中使用 :

在这里插入图片描述

setup中使用:

必须要加toRefs才是响应式的,数据的改变还是要commit到store中改变
在这里插入图片描述
和vue-router一样
use是vue使用库会用的一个函数
在script中使用这些库(store和router)都是用hook的方式,useRouter,useStore
(hooks:钩子函数,回调函数,就是一些函数)

单一状态树

就是只有一个store状态库,但里面可以有很多对象。
在这里插入图片描述
在这里插入图片描述

vuex只能有一个store,但是可以有module,pinia则不一样,可以有多个store

组件获取状态

在这里插入图片描述

使用mapState(映射方法)拿到数据(了解,不行可以不用)

就是在computed里面使用mapState方法,这样就可以直接用state里的数据,不用写一长串了。

在options api中的写法:

在computed()里面去写,这里分别是数组语法和对象语法:
在这里插入图片描述
在template中使用就是:
在这里插入图片描述

对象语法的好处就是可以重新命名,这样就可以减少冲突:
在这里插入图片描述

在setup语法中使用mapState(麻烦,做个了解)

无法直接用,因为直接用mapState拿是函数,在视频里讲了好几个方法,就记一下最好用的方法吧:

在这里插入图片描述
这样就可以直接用了

这个是老师封装的一个方法。
在这里插入图片描述

geetters使用

某些属性需要变化才用,例如统计所有人的成绩,或者要乘一下再用,这些操作都放在getters里面完成

在这里插入图片描述
第二个参数可以是getters
在这里插入图片描述

在这里插入图片描述

在getters中处理:
在这里插入图片描述

具体使用:
在这里插入图片描述
那么其实在这里这么长的表示都应该放到computed里面封装一下
例:

computed:{
    
    
	message(){
    
    
		return $store.getters.message
}
}

geetters的映射使用——mapGetters(麻烦 大可不用)

options api写法

直接写好就可以唉template里用了,就很方便
在这里插入图片描述

setup写法(也很不方便)

记住这些操作就是为了方便去使用store里的数据

方法1:加toRefs变成响应式
在这里插入图片描述
方法2:
在这里插入图片描述

Mutation基本使用

这些都是在options api里面进行操作的
在这里插入图片描述

这个就像父子组件里在父组件的methods里面进行操作,只不过是用state,没有tihs了

别忘了在方法()里加上state
在这里插入图片描述
传入的参数名是payload(可以随便命名。但是一般叫这个),还有就是可以传入一个对象,这样可以做的修改就更多的,最后一个就是传入了一个对象,叫newInfo

所以在子组件里面也要传出相应的事件:commit

在这里插入图片描述
这里最后传入的就是一个对象,可以进行的操作就更多。
此外,要记住这个和之前的父子通信一样,传入的是事件名,可以随便写,但是一般和子组件的方法名相同,这样也好理解,同时也要和在mutation中的方法名也要保持一致

在这里插入图片描述

常量类型(多次一举的规范,了解)

多加一步,为了防止在某一个地方写错,导致无法使用,引用常量,只要在常量里没有写错就不会写错

创建一个mutation_types的js文件,在里面创建变量并导出,只要这里的事件名没有写错就不会出错
在这里插入图片描述
在组件中导入这个变量并使用
在这里插入图片描述在这里插入图片描述

在store的js文件中也导入变量并使用
在这里插入图片描述

在这里插入图片描述

关于中括号:就是使用这个变量名而已
在这里插入图片描述
感觉是多次一举,主要是防止出错吧

mapMutation辅助函数(了解)

在这里插入图片描述
一样都行,就是语法糖。
options api:
不用写方法了
在这里插入图片描述

setup api:
极其麻烦
在这里插入图片描述

mutation 重要原则(重要)

不要在里面写异步操作
在这里插入图片描述

actions使用( 重要从参数:context)

向后端发送网络请求
因为真实的数据都是从网络请求拿到的(要放到store里面),由于异步操作的需要,引出actions

所以actions是用来进行网络数据请求的。

要特别记住actions和mutation的区别,面试会问到
actions提交的是mutation,但是mutation是直接变更状态
在这里插入图片描述
接受的不一样 是context(上下文),里面有很多东西,就是像一个store

store中书写actions

执行事件操作必须要context.commit(‘事件名’),调用的还是mutation里的事件处理方法
在这里插入图片描述
可以看到传入的是context,在处理事件的时候还是要commit调用store里面的函数来处理

特别注意:在actions中的事件名要加一个Action用以区别,否则名字就都是一样的了,不好理解。

在组件中使用action

action——dispatch(派发)

options:
在这里插入图片描述

setup:

在这里插入图片描述

在这里插入图片描述

mapActions也是做一个了解就好了:
在这里插入图片描述

在这里插入图片描述

数据方案

两种方案

1.数据在页面中进行维护
(获取的数据和自己创建的数据混在一起,就会不好)

2.数据在vuex里面维护(这里面还有模块,这样数据结构更加清晰)

这样感觉结构更清晰,那就是数据和页面是分开的 不会揉在一起

在这里插入图片描述

在actions中获取数据

网络数据地址

步骤

  1. 在actions中创建 fetchHomeMultidataAction(context) 函数用fetch拿到数据并最后用json返回成data
  2. 要赋值给state中的数据,这样后面页面才可以使用到,依然是commit并传入参数提交到mutation里
  3. 在state中声明要使用的的数据
  4. 在mutation中赋值banners
    这里有一个问题,那就是不应该把数据分开传进去,还不如直接传一个object对象data进去,不然还要写好多遍,太麻烦

看完视频最后发现它把数据的获取抽成了单独的一个组件module(简单来说就是单独的一个js文件,export然后在主index.js里面导入即可)
看完它的抽取就发现写的清晰多了,确实舒服多,如果放在大的store里面,会看起来很累。
在这里插入图片描述


fetch拿到数据,返回一个promise(res),然后转换成json格式,再返回一个promise(data)
这里是不同的几种获取方式,我觉得第一种最方便

    fetchHomeMultidataAction(context) {
    
    
      // 1.返回Promise, 给Promise设置then
      fetch("http://123.207.32.32:8000/home/multidata").then(res => {
    
    
        res.json().then(data => {
    
    
          console.log(data)
        })
      })
      
      //写法3 这一块在es6没有好好了解
      //手动返回promise 这里主要是缺少相关知识点了解
	  return new Promise(async (resolve, reject) => {
    
    
        // 3.await/async  异步函数自动返回promise
        const res = await fetch("http://123.207.32.32:8000/home/multidata")
        const data = await res.json()

      // 修改state数据,这里也是要传mutation里面处理,把数据传进去
        context.commit("changeBanners", data.data.banner.list)
        context.commit("changeRecommends", data.data.recommend.list)

 resolve("aaaaa")
      

组件中使用获取到的数据

要先把数据导进来,所以要使用actions里获取数据的方法,dispatch,这个也可以在onMounted这样的生命周期函数里面写好。
这里还有一点就是在执行之后会在控制台打印。
在这里插入图片描述
页面上:

所这里也可以看到要获取的数据要提前在state里声明才可以使用
在这里插入图片描述
在这里插入图片描述

promise一定要学好 ,现在前端对promise要求很高

忘记是很正常的,重要的是到时候用的时候回顾起来就行了

因为东西学了不用就会忘很正常,所以之前学的时候要做好笔记,到时候捡起来就快了。
多写作记多背,跟自己比较,最重要的是每天都有进步,不要焦虑。


module的基本使用

在这里插入图片描述

module就比较好理解,主要是为了抽取逻辑出来,比如说之前的从服务器获取数据那一个逻辑,当时揉在index.js的store里面看起来就特别的累,这个时候把它抽出来(home.js),叫做homeModule,再导入进去,这样就看起来清晰多了,把一个逻辑的东西放到一起,这个时候维护起来也方便

在index.js里:
在这里插入图片描述
store的modules: 这里是进行重命名
在这里插入图片描述

在组件中使用:
在这里插入图片描述
ps:在setup里的内容就不用改了

module的局部状态

在这里插入图片描述
也特别好理解,就是这里面的state不是index.js里的state,就是在这个文件里的state,如果要用外面的数据,要用rootState

组件中使用:默认是不用加模块名的,但是这样就是在全局去找,因为模块也是在全局的
在这里插入图片描述

此外,在模块里命名要特别小心,注意不要和store里的重复了,一旦重复,调用的就是store里的,而非模块里的,因为在调用的时候是不用加模块的,所以这个时候就有命名空间来解决这个问题

在这里插入图片描述
这个时候拿的时候就要加上模块名:
在这里插入图片描述

到这里就结束了,把模块的这个用法掌握就好了。

这个随便看看吧
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Tommy__li/article/details/128761920