返回顶部
首页 > 资讯 > 前端开发 > node.js >vuex不建议在action中修改state的原因是什么
  • 857
分享到

vuex不建议在action中修改state的原因是什么

2024-04-02 19:04:59 857人浏览 安东尼
摘要

这篇文章给大家分享的是有关Vuex不建议在action中修改state的原因是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一起阅读源码吧~1.首先我们可以在src/stor

这篇文章给大家分享的是有关Vuex不建议在action中修改state的原因是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

一起阅读源码吧~

1.首先我们可以在src/store.js这个文件的Store类中找到下面这段代码

// ...
this.dispatch = function boundDispatch (type, payload) {
 return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload, options) {
 return commit.call(store, type, payload, options)
}
// ...

上面是Vuex两个最核心的api:dispatch & commit,它们是分别用来提交action和mutation的

那么既然我们今天的目的是为了“了解为什么不能在action中修改state”,所以我们就先看看mutation是怎样修改state的,然而mutation是通过commit提交的,所以我们先看一下commit的内部实现

commit&mutation

2.commit方法的核心代码大致如下:

commit (_type, _payload, _options) {
  // ...
  this._withCommit(() => {
   entry.forEach(function commitIterator (handler) {
    handler(payload)
   })
  })
  // ...
}

不难看出,Vuex在commit(提交)某种类型的mutation时,会先用_withCommit包裹一下这些mutation,即作为参数传入_withCommit;那么我们来看看_withCommit的内部实现(ps:这里之所以说”某种类型的mutation“,是因为Vuex的确支持声明多个同名的mutation,不过前提是它们在不同的namespace下;action同理)

3._withCommit方法的代码如下:

_withCommit (fn) {
  const committing = this._committing
  this._committing = true
  fn()
  this._committing = committing
 }

是的,你没有看错,它真的只有4行代码;这里我们注意到有一个标志位_committing,在执行fn前,这个标志位会被置为true,这个点我们先记下,一会儿会用到

4.接下来,我要为大家要介绍的是resetStoreVM这个函数,它的作用是初始化store,它首次被执行是在Store的构造函数中

function resetStoreVM (store, state, hot) {
 // ...
 if (store.strict) {
  enableStrictMode(store)
 }
// ...
}

在这里有一处需要我们注意:resetStoreVM对strict(是否启用严格模式)做了判断,这里假设我们启用严格模式,那么就会执行enableStrictMode这个函数,下面继续来看看它的内部实现

function enableStrictMode (store) {
 store._vm.$watch(function () { return this._data.$$state }, () => {
  if (process.env.node_ENV !== 'production') {
   assert(store._committing, `do not mutate vuex store state outside mutation handlers.`)
  }
 }, { deep: true, sync: true })
}

这里对Vue组件实例的state做了监听,一旦监听到变化,就会执行asset(断言),它断言的恰巧就是刚才我让大家记住的那个_committing标志位,那么我们再来看看这个asset做了些什么

5.asset方法在src/util.js这个文件中

export function assert (condition, msg) {
 if (!condition) throw new Error(`[vuex] ${msg}`)
}

这个方法很简单,就是判断第一个参数是否为truly值,如果不为真,就抛出一个异常
到此,我们已简单地了解了commit和mutation的逻辑,下面再来看看dispatch和action

dispatch&action

6.dispatch代码大致如下:

dispatch (_type, _payload) {
  const {
   type,
   payload
  } = unifyObjectStyle(_type, _payload)

  const action = { type, payload }
  const entry = this._actions[type]

 // ...
  const result = entry.length > 1
   ? Promise.all(entry.map(handler => handler(payload)))
   : entry[0](payload)
 // ...
 }

这里我们注意到,当某种类型的action只有一个声明时,action的回调会被当作普通函数执行,而当如果有多个声明时,它们是被视为Promise实例,并且用Promise.all执行,总所周知,Promise.all在执行Promise时是不保证顺序的,也就是说,假如有3个Promise实例:P1、P2、P3,它们3个之中不一定哪个先有返回结果,那么我们仔细思考一下:如果同时在多个action中修改了同一个state,那会有什么样的结果?

其实很简单,我们在多个action中修改同一个state,因为很有可能每个action赋给state的新值都有所不同,并且不能保证最后一个有返回结果action是哪一个action,所以最后赋予state的值可能是错误的

那么Vuex为什么要使用Promise.all执行action呢?其实也是出于性能考虑,这样我们就可以最大限度进行异步操作并发
眼尖的同学可能已经发现在dispatch中并没有看到_committing的身影,就是Vuex对action修改state的限制:当action想要修改state时,因为_committing没有事先被置为true,而导致asset阶段无法通过

但这个限制只限于开发阶段,因为在enableStrictMode函数中,webpack加入了对环境的判断,如果不是生产环境(也就是开发环境)才会输出asset(断言)这行代码

function enableStrictMode (store) {
 store._vm.$watch(function () { return this._data.$$state }, () => {
  if (process.env.NODE_ENV !== 'production') {
   assert(store._committing, `do not mutate vuex store state outside mutation handlers.`)
  }
 }, { deep: true, sync: true })
}

那么也就是说如果你强行在生产环境中用action修改state,Vuex也不会阻止你,它可能仅仅是给你一个警告;而且按道理来说,如果我们能够保证同一类型的action只有一个声明,那么无论是使用action还是mutation来修改state结果都是一样的,因为Vuex针对这种情况,没有使用Promise.all执行action,所以也就不会存在返回结果先后问题

dispatch (_type, _payload) {
  // ...
  const result = entry.length > 1
   ? Promise.all(entry.map(handler => handler(payload)))
   : entry[0](payload)
  // ...
 }

但是凡是靠人遵守的约定都是不靠谱的,所以我们在平时使用Vuex时,最好还是遵守官方的约束,否则线上代码有可能出现bug,这不是我们所期望的。

感谢各位的阅读!关于“vuex不建议在action中修改state的原因是什么”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: vuex不建议在action中修改state的原因是什么

本文链接: https://lsjlt.com/news/76573.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • vuex不建议在action中修改state的原因是什么
    这篇文章给大家分享的是有关vuex不建议在action中修改state的原因是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一起阅读源码吧~1.首先我们可以在src/stor...
    99+
    2024-04-02
  • MySQL中不建议使用SELECT *的原因是什么
    本篇内容介绍了“MySQL中不建议使用SELECT *的原因是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!“不要使用...
    99+
    2023-06-29
  • MyBatis中不建议使用where 1=1的原因是什么
    这篇文章主要介绍了MyBatis中不建议使用where 1=1的原因是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇MyBatis中不建议使用where 1=1的原因...
    99+
    2023-07-02
  • MySQL中不建议使用Delete删除数据的原因是什么
    今天就跟大家聊聊有关MySQL中不建议使用Delete删除数据的原因是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。InnoDB存储架...
    99+
    2024-04-02
  • java不建议用equals判断对象相等的原因是什么
    这篇文章主要介绍“java不建议用equals判断对象相等的原因是什么”,在日常操作中,相信很多人在java不建议用equals判断对象相等的原因是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java不...
    99+
    2023-07-05
  • 修改IP地址后上不了网是什么原因
    这篇文章主要介绍“修改IP地址后上不了网是什么原因”,在日常操作中,相信很多人在修改IP地址后上不了网是什么原因问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”修改IP地址后上不了网是什么原因”的疑惑有所帮助!...
    99+
    2023-06-20
  • 不能在PHP中使用泛型的原因是什么
    小编给大家分享一下不能在PHP中使用泛型的原因是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么我们不能在 PHP 中使用泛型我们将深入探讨泛型和 PHP...
    99+
    2023-06-29
  • 不在分页中使用offset和limit的原因是什么
    这篇文章主要讲解了“不在分页中使用offset和limit的原因是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“不在分页中使用offset和limit的...
    99+
    2024-04-02
  • Spring中@Configuration注解修改的类生成代理的原因是什么
    今天小编给大家分享一下Spring中@Configuration注解修改的类生成代理的原因是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们...
    99+
    2023-06-29
  • es6中不用var而是用let的原因是什么
    本文小编为大家详细介绍“es6中不用var而是用let的原因是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“es6中不用var而是用let的原因是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深...
    99+
    2024-04-02
  • 不要在PHP接口URL中添加后缀的原因是什么
    这篇文章主要介绍了不要在PHP接口URL中添加后缀的原因是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇不要在PHP接口URL中添加后缀的原因是什么文章都会有所收获,下面我们一起来看看吧。为什么不要在PHP...
    99+
    2023-07-05
  • MySQL中不使用Text类型的原因是什么
    MySQL中不使用Text类型的原因是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。众所周知,MySQL广泛应用于互联网的OLTP(联机事...
    99+
    2024-04-02
  • Python中不支持 switch 语句的原因是什么
    这期内容当中小编将会给大家带来有关Python中不支持 switch 语句的原因是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、switch 是什么switch 的语法格式如下:switch(ex...
    99+
    2023-06-16
  • thinkphp中类不存在的三种原因和解决方法是什么
    这篇“thinkphp中类不存在的三种原因和解决方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“thinkphp中类...
    99+
    2023-07-05
  • HTTP协议在Java教程中的实现原理是什么?
    HTTP协议是现今最流行的网络协议之一,Java语言也提供了多种方式来实现HTTP协议。在本文中,我们将深入探讨HTTP协议在Java教程中的实现原理。 HTTP协议简介 在探讨HTTP协议在Java中的实现原理之前,我们需要先了解HTT...
    99+
    2023-06-17
    教程 http 自然语言处理
  • CSS中overflow-y: visible;不起作用的原因是什么
    这篇文章主要介绍CSS中overflow-y: visible;不起作用的原因是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!场景最近要做的一个需求是移动端的h6页面,要求有一排可选择的卡片, 超出容器部分可以左...
    99+
    2023-06-08
  • JS中小数相加不精确的原因是什么
    这篇文章主要介绍“JS中小数相加不精确的原因是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JS中小数相加不精确的原因是什么”文章能帮助大家解决问题。Javascript中小数相加的问题在Jav...
    99+
    2023-07-06
  • idea中修改不重启的方法是什么
    在修改Idea配置文件时,有一些更改可以在不重启IDE的情况下生效。以下是一些常见的方法:1. 使用IDEA的重载配置功能:在“He...
    99+
    2023-08-08
    idea
  • React不将Vite作为构建应用的首选原因是什么
    这篇文章主要介绍“React不将Vite作为构建应用的首选原因是什么”,在日常操作中,相信很多人在React不将Vite作为构建应用的首选原因是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”React不将...
    99+
    2023-07-05
  • 在js中修改html body的样式是什么
    这期内容当中小编将会给大家带来有关在js中修改html body的样式是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、原始定义先在css中定义:body, html 宽高为300pxbody,&n...
    99+
    2023-06-25
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作