• 关于Vuex的简单理解和使用


    1、什么是Vuex?

    在使用vue作为框架的前端项目开发中,我们经常会碰到Vuex,那么Vuex到底是什么东西呢?

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

    简单来说,Vuex就是一个状态管理的库,或者说是一个用来存放组件公共数据的仓库。

    2、为什么要使用Vuex

    要了解为什么要使用Vuex,那么我们就需要先来了解vue项目中组件之间的传参方式

    2.1、组件之间的传参方法

    父组件向子组件传参:

    // 父组件传递参数
    
    
    
    
    // 子组件接收参数
    
    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    子组件向父组件传参:

    // 父组件
    
    
    
    
    // 子组件
    
    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    组件之间跳转的传参方法(示例由组件A跳转到组件B):

    // A组件
    
    
    
    
    // B组件
    
    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    从上面三种组件之间传参的方式我们可以看出,组件与组件之间传递参数实现数据共享,那么组件之间需要有一定联系,要么是父子组件,要么是有跳转的关系,才能实现数据的共享。可是在完全没有联系的组件之间,他们如何实现数据的共享呢?

    要想实现完全没有联系的组件之间数据共享,我们需要先思考一个问题,什么样的数据,需要同时在几个没有联系的组件中去使用呢?

    2.2、 数据共享的情景

    在项目开发中,我们经常会碰到一种情景,比如说一个系统,在用户登录之后,后端会将该用户的一些数据返回给前端,如用户名,token等,而这些用户数据往往不止在一个页面中使用,可能涉及到多个相互没有联系的组件,那么在这种时候,我们就需要使用到Vuex。

    3、Vuex的使用

    对于一个插件的使用,我们首先需要看对应的官方文档:Vuex 是什么? | Vuex (vuejs.org)。根据文档,接下来我们来一起理解Vuex。

    在Vuex中有五个属性,分别为state,getters,mutations,actions,modules,下面我们将从这五个属性来学习Vuex。

    3.1、state属性:

    从上面的概念我们知道,Vuex是用来存放一些共享的数据,实现状态管理的一个插件,那么,我们的这些数据要放在那里呢?

    在项目目录下,我们可以找到一个名为store的文件夹,文件夹中存放一个index.js的文件

    我们之后关于Vuex的一些操作,基本都会在这个文件夹下的文件中实现。

    首先我们来看一下index.js文件中都有些什么

    // 导入vue
    import Vue from 'vue'
    // 导入Vuex
    import Vuex from 'vuex'
    // 注册Vuex组件
    Vue.use(Vuex)
    
    // 导出Vuex.Store
    export default new Vuex.Store({state: {},getters: {},mutations: {},actions: {},modules: {}
    }) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们可以看到,index.js中的内容基本和其他的插件的使用方式一样,我们主要看Vuex.Store中的内容,我们可以看到前面讲到的五个属性就是在Vuex.Store中,而我们的数据,就会放在state中。那么,怎么使用这个数据呢,我们使用文档中举的例子来示例。

    首先,我们需要在state中加入我们要在其他组件中使用的数据

    // store/index.js
    export default new Vuex.Store({state: {// 添加一个变量numnum: 0},
    }) 
    
    • 1
    • 2
    • 3

    在store中添加了数据之后,我们需要到对应的组件中使用

    组件A中使用

     
    
    • 1
    • 2

    组件B中使用

    
    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里我举例了两种组件调用state中数据的方法,文档中还提到了其他的方法,可以自行查看。

    到这里我们发现,我们已经实现了将数据存放在一个地方,可以供多个不相关的组件一起调用,那么好像数据共享就完成了一部分,但是我们也知道,前端的数据往往不是单纯地进行展示,而是需要进行操作,那么,对于Vuex中的数据,我们要怎么进行操作呢?

    按照前端开发的思路,原则上只要我们获取到数据,好像就可以对数据进行操作了,我们既然通过store.state.num可以获取到num,那么对store.state.num可以获取到num,那么对store.state.num可以获取到num,那么对store.state.num进行操作就可以了,按这个思路,我们可以看看是否成功?

    
    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5

    通过试验,我们发现,页面展示的数据确实达到了想要的效果,但是通过Vue开发者工具,我们发现,Vuex的state一直都没有改变

    很显然,我们不能直接通过$store.state.num来改变数据,那么我们到底需要怎么样改变数据呢?

    3.2、mutations属性:

    通过看Vuex的文档,我们可以在mutations属性介绍中发现这样一句话:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。那么根据这句话,我们就可以知道,想要修改num,必须提交mutation,根据文档的使用方法,我们更改一下代码:

    
    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // store/index.js
    export default new Vuex.Store({state: {// 添加一个变量numnum: 0},mutations: {addNum(state) {state.num++;}},
    }) 
    
    • 1
    • 2
    • 3

    结果也符合预期:

    那么到这里,数据的展示和操作好像都已经完成了,可是我们发现,还有三个属性都没有用到,那么这三个属性又有什么样的用处呢?

    3.3、actions属性:

    我们知道,在实际的项目开发中,我们会碰到很多异步操作,比较常见的就用axios请求,定时器等,那么我们对Vuex中的数据进行异步操作时是不是还是使用mutations呢?

    很显然,大家看目录到这里,就知道对Vuex中的数据进行异步操作是要用到actions的,但是我们在学习mutations的时候有了解到更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,那么actions是如何提交mutation的呢?

    export default new Vuex.Store({state: {// 添加一个变量numnum: 0},mutations: {addNum(state) {state.num++;}},actions: {addNum(context) {setTimeout(() => {context.commit('addNum')},1000)}},
    }) 
    
    • 1
    • 2
    
    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们可以看到在action中,有一个addNum方法接收了一个context参数,然后再方法中有一个定时器,定时器中通过conntext.commit调用了addNUm,看到.commit我们就会看到调用mutations时用的就是**this.store.commit(′addNum′),∗∗那是不是达标,action接收的那个context参数就是this.store.commit(‘addNum’),** 那是不是达标,action接收的那个context参数就是this.store.commit(′addNum′),∗∗那是不是达标,action接收的那个context参数就是this.store呢?我们使用console.log分别输出this.$store和context

    在控制台中,我们可以看到,这两者有类似的属性,但是又不完全相同,但是,两者都有着同样的方法,那么就有可能是,context与store存在着某些联系,可以通过context.commit提交mutations。根据文档给出的解释是,Action函数接收了一个与store实例具有相同方法和属性的context对象,使我们可以通过context.commit来提交mutations。

    3.4、modules属性:

    modules的中文意思是模块,那么见名思意,我们可以大致理解为modules属性就是用来存放模块的。那么,在存放模块之前,就意味着我们需要现有模块。

    在Vuex中,是允许我们将store分割成模块,每个模块拥有自己的state,mutations,action,getters甚至是modules,那么我们想象一下,为什么我们需要将store分割成模块呢?

    我们知道,组件化开发,可以将根据功能划分组件,然后再讲组件整合在一起,这样既有利于我们分工,也增加了代码的复用性和便于后期的维护。而将store显然也是出于这样的考虑,我们知道,在一个大型的项目,需要进行状态管理的数据往往不是一两个变量,而是一个很复杂庞大的数据,如果我们将这些数据全部写到index.js文件中,那么整个文件就会显得冗余,而是可读性很低,那么这时候就需要我们将这些数据分割成不同的模块。

    // store/index.js
    export default new Vuex.Store({state: {},mutations: {},actions: {},modules: {user,menu,tab}
    }) 
    
    • 1
    • 2
    • 3

    例如这样,我们就可以根据我们的需要,将user和menu的数据分割成一个模块,这样store/index.js这个文件就会显得很精简,而且也便于我们的更改。

    3.5、getters属性:

    getters这个属性主要用于对state中的数据进行一些数据处理,在某种程度上来说,比较像组件中的computed。这里的数据处理和上面的mutations的数据操作并不是同一个意思。

    getters的数据数据处理是指将state处理之后在组件中展示,而mutations则是指在触发某些事件之后对数据进行对应的操作。

    举个例子,我们现在state中的num是0,我们知道在点击事件提交mutations之后num会加1,但是我们现在希望在增加多一个变量的前提下,组件A展示的是1,组件B展示的是0,那么在这个时候,我们就需要用到getters对state的num进行数据处理

    export default new Vuex.Store({state: {// 添加一个变量numnum: 0},getters: {getAddNum(state) {return state.num+1} },mutations: {addNum(state) {state.num++;}},actions: {addNum(context) {console.log("context",context)setTimeout(() => {context.commit('addNum')},1000)}},
    }) 
    
    • 1
    • 2

    组件A:

     
    
    • 1
    • 2

    这样,我们就可以达成我们的目的:

    4、总结

    Vuex的使用还有很多需要注意的地方,本文只是简单的理解Vuex的几个属性的使用方法。

    需要注意的地方是:由于Vuex的版本升级,很多地方进行了修正(详情可以查看官方文档),本文的代码是基于"vuex": "^3.4.0"版本的,如果按本文的代码练习出现错误,请寻找对应的Vuex版本代码进行学习。

  • 相关阅读:
    vscode中Emmet语法的使用
    聊聊网络编程中的粘包、拆包、半包、编解码
    HTTP相关知识
    Html-盒子模型
    Oracle PrimaveraUnifier空间管理器(Space Manager)
    JavaScript爬虫程序实现自动化爬取tiktok数据教程
    [PSQL] 复杂查询
    计算机的前世今生
    【设计模式】第2节:七大设计原则
    CSRF和XSS是什么?有什么区别?
  • 原文地址:https://blog.csdn.net/weixin_53312997/article/details/126859558