vuex实现原理

vuex实现原理,第1张

vuex是在每个组件上注入this store获取共享的状态,定义 *** 作state的方法

首先使用vueuse(vuex)表明vuex是vue的插件,只能被vue使用——实例化Store并传入参入——Store注入到根组件上。以上三个步骤便可以使用vuex实现数据在组件中的共享了。

当使用到vueuse的时候,会调用Store文件中的install方法,并可以获取到当前组件的执行期上下文。通过全局混合的方式,在每个组件上嵌入this$store属性。

当Store类被实例化时,会执行constructor构造器并且传入option所需的参数,在对state、getters、mutations、actions编写。

1、实现state:理论上讲,直接把参数中的state赋值当前组件上即可,这样会引发一个问题,state的值无法动态改变。要使用state双向绑定可以直接使用vue实例中data方法,然后在通过get进行属性的截取。

2、实现getters:通过OjbectdefineProperty监听getters值里面的变化,当获取值的时候,会触发get方法,返回并执行参数getters里面的方法。

3、实现mutations:把参数mutations里面的方法重新用一个变量去接收,作用是防止变量的全局污染。定义commit函数,当被执行时,触发定义mutaion对象里面的方法。

4、实现actions:方法同上,有个地方需要作出微调,传递的参数是当前的执行期上下文。

项目案例

在ajax回掉中添加callback;

methods:{

callback:function(_this){

consolelog(_this)

}

ajax回掉:function(){

thiscallback(this)

}

}

vue中的异步问题困扰了好久,终于解决了,mark一下给需要的朋友。

项目开始使用vuex来解决组件之间变量传值的问题。但是用着用着出现了一个问题,子组件中用到mapboxMap属性,而mapboxMap属性值需要等待父组件初始化函数执行完之后才会有,这就存在一个异步的问题,页面已初始化加载的时候mapboxMap是为undefined,解决方法为在子组件中监听mapboxMap的值,具体方法如下:

父组件中:

子组件中

全局状态管理器,可以在项目的任何一个组件中去获取和修改,修改可以得到全局响应的变量

vue-cli2 项目中安装vuex,使用 npm install vuex --save

安装成功后,在src目录下新建一个store文件,里面创建一个js文件

在js文件中写入:

然后在mainjs文件中引入 store 并注册到 vue 实例中

vuex的文件配置到这里就完成了

现在再回去看store文件里的参数,这几个对象就是vuex五大核心:

State :可全局访问的对象

Getter :和vue的computed一样,用来实时监听state的值的变化(最新状态)

Mutation :存放改变state值的方法(同步)

Action :触发mutations里面的方法(异步)

module :模块

State是存储在Vuex中的数据对象,和Vue实例中的data一样。只不过State是可以全局访问的。

定义stata对象,直接在 state 里面定义 key:val ,它可以定义任意数据类型

在页面中获取state的值 使用 this$storestate

在这里 state 通常都是挂载到 computed 计算属性上,这样当state的值发生改变的时候都能及时的响应。

当然也能用到 watch 去监听

State中的辅助函数 mapState

当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性

输出

Vuex 允许我们在 store 中定义 getter (可以认为是 store 的计算属性)。就像计算属性 computed 一样, getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值( state 中的属性)发生了改变才会被重新计算。

Getter的作用就是用来实时监听state的值的变化

定义Geters对象

使用 state 作为其第一个参数

可以使用其他 getter 函数作为第二个参数

在页面中使用getters,使用 this$storegetters

Getters中的辅助函数 mapGetters

mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:

输出

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

使用 state 作为第一个参数

使用 this$storecommit('方法名') 触发mutations中的方法

输出

而第二参数官方解释叫 提交载荷(Payload)

可以向 storecommit 传入额外的参数,即 mutation 的 载荷(payload)

简单来说就是可以在在第二参数里传入额外的参数

这里还是用name来做例子

输出

在 Vuex 中,mutation 必须是同步函数

Action 可以包含任意异步 *** 作,Action的作用就是异步触发Mutations

定义action对象

接收一个 context 参数和一个要变化的形参

context 与 store 实例具有相同的方法和属性,所以他可以执行 contextcommit("") ,也可以使用 contextstate 和 contextgetters 来获取 state 和 getters 。

使用 this$storedispatch("方法名") 方法执行Actions

输出

同样Action还支持载荷方法,传入第二形参

输出

其中 module 的作用是可以把 store 分割成模块(module),每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

主要是为了解决由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

简单来说就是可以把vuex模块化

VueX 是适用于在 Vue 项目开发时使用的状态管理工具。试想一下,如果在一个项目开发中频繁的使用组件传参的方式来同步 data 中的值,一旦项目变得很庞大,管理和维护这些值将是相当棘手的工作。为此, Vue 为这些被多个组件频繁使用的值提供了一个统一管理的工具—— VueX 。在具有 VueX 的Vue项目中,我们只需要把这些值定义在VueX中,即可在整个Vue项目的组件中使用。

由于 VueX 是在学习 VueCli 后进行的,所以在下文出现的项目的目录请参照 VueCli 2x 构建的目录。

以下步骤的前提是你已经完成了Vue项目构建,并且已转至该项目的文件目录下。

打开mainjs

例如在Appvue中,我们要将state中定义的name拿来在h1标签中显示

或者要在组件方法中使用

注意,请不要在此处更改 state 中的状态的值,后文中将会说明

在Vue项目开发中,需要监控项目中得各种值,为了提高效率,Vue提供了一款浏览器扩展——VueDevtools。

在学习VueX时,更为需要使用该插件。关于该插件的使用可以移步官网,在此不再赘叙。

在VueX对象中,其实不止有 state ,还有用来 *** 作 state 中数据的方法集,以及当我们需要对 state 中的数据需要加工的方法集等等成员。

成员列表:

首先, Vue 组件如果调用某个 VueX 的方法过程中需要向后端请求时或者说出现异步 *** 作时,需要 dispatch VueX中 actions 的方法,以保证数据的同步。可以说, action 的存在就是为了让 mutations 中的方法能在异步 *** 作中起作用。

如果没有异步 *** 作,那么我们就可以直接在组件内提交状态中的 Mutations 中自己编写的方法来达成对 state 成员的 *** 作。注意, 133节 中有提到,不建议在组件中直接对 state 中的成员进行 *** 作,这是因为直接修改(例如: this$storestatename = 'hello' )的话不能被 VueDevtools 所监控到。

最后被修改后的state成员会被渲染到组件的原位置当中去。

mutations 是 *** 作 state 数据的方法的集合,比如对该数据的修改、增加、删除等等。

mutations 方法都有默认的形参:

( [state] [,payload] )

例如,我们编写一个方法,当被执行时,能把下例中的name值修改为 "jack" ,我们只需要这样做

indexjs

而在组件中,我们需要这样去调用这个 mutation ——例如在Appvue的某个 method 中:

在实际生产过程中,会遇到需要在提交某个 mutation 时需要携带一些参数给方法使用。

单个值提交时:

当需要多参提交时,推荐把他们放在一个对象中来提交:

接收挂载的参数:

另一种提交方式

为了配合Vue的响应式数据,我们在Mutations的方法中,应当使用Vue提供的方法来进行 *** 作。如果使用 delete 或者 xxxx = xx 的形式去删或增,则Vue不能对数据进行实时响应。

可以对state中的成员加工后传递给外界

Getters中的方法有两个默认参数

例如

组件中调用

由于直接在 mutation 方法中进行异步 *** 作,将会引起数据失效。所以提供了Actions来专门进行异步 *** 作,最终提交 mutation 方法。

Actions 中的方法有两个默认参数

例如,我们在两秒中后执行 222 节中的 edit 方法

由于 setTimeout 是异步 *** 作,所以需要使用 actions

在组件中调用:

改进:

由于是异步 *** 作,所以我们可以为我们的异步 *** 作封装为一个 Promise 对象

当项目庞大,状态非常多时,可以采用模块化管理模式。Vuex 允许我们将 store 分割成 模块(module) 。每个模块拥有自己的 state、mutation、action、getter 、甚至是嵌套子模块——从上至下进行同样方式的分割。

组件内调用模块a的状态:

而提交或者 dispatch 某个方法和以前一样,会自动执行所有模块内的对应 type 的方法:

如果把整个 store 都放在 indexjs 中是不合理的,所以需要拆分。比较合适的目录格式如下:

对应的内容存放在对应的文件中,和以前一样,在 indexjs 中存放并导出 store 。 state 中的数据尽量放在 indexjs 中。而 modules 中的 Astore 局部模块状态如果多的话也可以进行细分。

        将VueX安装在生产环境依赖中

        npm  install  vuex  --save

     说明:

        1   通过vue实例中的store选项

        2   是为了将store对象挂Vue的原型$store上

        3  这样所有的组件内部就可以使用 this$store 来 *** 作store

             所谓的单一状态树,用一个对象包含应用中全部的状态,这个对象作为唯一数据源而存在。也就是意味着每个应用只包含一个store实例。

             在组件中使用state中的数据

     示例总结:

        1  可以直接修改Vuex中的状态(但不推荐),因为直接修改不利于调试

    1 有的是我们对于store里的state中派生一些状态出来,如:数据的过滤

    2 在获取数据后进行过滤处理,同样的逻辑可能会在不同的地方使用

    3 在Vue中也可以采用计算属性进行处理(计算属性就是会将数据处理进行缓存的)

    4  Vuex提供了一个getter,类似于store中的计算属性,根据依赖状态计算值后返回并缓存起来

    5  只有当getter依赖的状态发生了改变时才会被重新计算

1  Getter的第一个参数为状态state,用于收获Getter的依赖状态

2  Getter的第二个参数

     Getter的第二个参数就是选项Getters,作用是用来获取其他Getter函数

3  通过方法访问

  说明:

     1  通常对于getter的使用方法,都是返回处理完毕后的数据

     2  但是有的时候我们需要处理数据的条件是外部传递过来的,例如示例过滤价格

     3  getter可以返回一个函数,这个函数用来接收外部传递的参数

总结:

    1、getter返回的不是确定的值而是一个函数

     2、那么此时在通过$storegettersfilterFruits获取到的就是一个函数

     3、既然是函数就可以当成方法使用, 传递参数

     4、如 $storegettersfilterFruits(20)

Vuex有五个核心概念:

1、state:vuex的基本数据,用来存储变量(后四个属性都是用来 *** 作state里面储存的变量的)。

2、getters:是对state里面的变量进行过滤的。

3、mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。

4、action:和mutation的功能大致相同,不同之处在于:

            1Action提交的是mutation,而不是直接变更状态。  也就是action是用来修改mutation并提交的  而  mutation是通过修改state

             2Action可以包含任意异步 *** 作。(一般比较复杂的数据都在action中 *** 作)

             3action先会执行异步 *** 作再去调用mutation,随后才跟新state

5、modules:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

dispatch:是跟action一块用的,含有异步 *** 作,例如向后台提交数据,写法: this$storedispatch('mutation的方法名',获取值)

commit:是跟mutation一块用的,同步 *** 作 ,写法: this$storecommit('mutation的方法名',获取值)

vue构建的项目中,vuex的状态存储是响应式的,当vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会得到高效刷新,问题来了,vuex存储的数据只是在页面中,相当于我们定义的全局变量,刷新之后,里面的数据就会恢复到初始化的状态。比如,用户已经登录了,我把登录状态放到state中了,一刷新页面,还要重新登录?购物车里的添加的数据,一刷新要重新添加?

vuex存取值一般都是放在computed计算属性中,但是一刷新页面的数据就没了

监听页面是否刷新,如果页面刷新了,将state对象存入到sessionStorage/localStorage中。页面打开之后,判断sessionStorage/localStorage中是否存在state对象,如果存在,则说明页面是被刷新过的,将sessionStorage/localStorage中存的数据取出来给vuex中的state赋值。如果不存在,说明是第一次打开,则取vuex中定义的state初始值。

以上就是关于vuex实现原理全部的内容,包括:vuex实现原理、如何在Vuex中获取组件vue实例、vue中监听Vuex中state内的变量,实现异步赋值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10145191.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存