state也就是vuex里的值,也即是整个vuex的状态,而strict和state的设置有关,如果设置strict为true,那么不能直接修改state里的值,只能通过mutation来设置

例1:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.1.0/dist/vuex.js"></script>
</head>
<body>
<div id="app">
<p>count:{{count}}</p>
</div>
<script>
const store = new Vuex.Store({
state:{count:1}
})
var app = new Vue({
el:"#app",
store,
computed:{
count(){return store.state.count }
}
})
</script>
</body>
</html>

渲染如下:

当我们在控制台修改store.state.coun里的值时页面会自动更新,例如:

此时页面自动更新了,变为了:

我们设置一个strict属性看看:例2:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.1.0/dist/vuex.js"></script>
</head>
<body>
<div id="app">
<p>count:{{count}}</p>
</div>
<script>
const store = new Vuex.Store({
state:{count:1},
strict:true //新增一个strict属性,值为true
})
var app = new Vue({
el:"#app",
store,
computed:{
count(){return store.state.count }
}
})
</script>
</body>
</html>

此时渲染如下:

当我们在控制台输入store.state.count=2后,如下:

控制台报错了,页面渲染如下:

可以看到设置strict后,虽然能直接更改vuex里的值,但是会出现一条报错信息,即严格模式下vuex会给出一条提示,提示我们只能通过mutation来修改。

源码分析


writer by:大沙漠 QQ:22969969

我们直接修改state会触发更新以及strict严格模式的控制都是在vuex内部resetStoreVM整个函数内实现的,如下:

  function resetStoreVM (store, state, hot) {       //重新存储数据
var oldVm = store._vm; // bind store public getters
store.getters = {}; //给store定义一个getters属性,值为一个对象
var wrappedGetters = store._wrappedGetters; //获取store的所有getter数组信息
var computed = {};
forEachValue(wrappedGetters, function (fn, key) { //遍历wrappedGetters
// use computed to leverage its lazy-caching mechanism
computed[key] = function () { return fn(store); }; //将getter保存到computed里面
Object.defineProperty(store.getters, key, { //设置store.getters的key的访问器属性
get: function () { return store._vm[key]; },
enumerable: true // for local getters
});
}); // use a Vue instance to store the state tree
// suppress warnings just in case the user has added
// some funky global mixins
var silent = Vue.config.silent; //保存Vue.config.silent的配置
Vue.config.silent = true; //设置Vue.config.silent配置属性为true(先关闭警告)
store._vm = new Vue({ //创建new Vue()实例把$$state和computed变成响应式的
data: {
$$state: state
},
computed: computed
});
Vue.config.silent = silent; //将Vue.config.silent复原回去 // enable strict mode for new vm
if (store.strict) { //初始化Strore时,如果给strict传入了true
enableStrictMode(store); //则调用enableStrictMode()函数
} if (oldVm) {
if (hot) {
// dispatch changes in all subscribed watchers
// to force getter re-evaluation for hot reloading.
store._withCommit(function () {
oldVm._data.$$state = null;
});
}
Vue.nextTick(function () { return oldVm.$destroy(); });
}
}

从上面看到vuex内部创建一个vue对象并把state设置为了data对象里,因此有响应式的功能,而如果传入了strict,则调用enableStrictMode函数,该函数实现如下:

  function enableStrictMode (store) {       //严格模式下,观察this._data.$$state的变化
store._vm.$watch(function () { return this._data.$$state }, function () { //如果this._data.$$state发生变化时,store._committing不为true,则报错(不是通过vuex的接口来修改时)
{
assert(store._committing, "do not mutate vuex store state outside mutation handlers.");
}
}, { deep: true, sync: true });
}

也就是调用vue.$watch去观察 this._data.$$state的变化,也就是vuex里的state的变化,如果有变化且store._committing不为true则报错

store._committing是vuex里的一个属性,如果是通过mutation修改state时就会设置store._committing为true,否则store._committing为false

vuex源码分析(二) state及strict属性 详解的更多相关文章

  1. Vue.js 源码分析(十) 基础篇 ref属性详解

    ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件实例,例如: ...

  2. JDK源码分析(12)之 ConcurrentHashMap 详解

    本文将主要讲述 JDK1.8 版本 的 ConcurrentHashMap,其内部结构和很多的哈希优化算法,都是和 JDK1.8 版本的 HashMap是一样的,所以在阅读本文之前,一定要先了解 Ha ...

  3. jQuery源码分析(九) 异步队列模块 Deferred 详解

    deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,比如一些Ajax操作,动画操作等.(P.s:紧跟上一节:https://www.cnblogs.com/grea ...

  4. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

  5. Spring源码分析之Bean的创建过程详解

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...

  6. jQuery 源码分析(十九) DOM遍历模块详解

    jQuery的DOM遍历模块对DOM模型的原生属性parentNode.childNodes.firstChild.lastChild.previousSibling.nextSibling进行了封装 ...

  7. jQuery 源码分析(十) 数据缓存模块 data详解

    jQuery的数据缓存模块以一种安全的方式为DOM元素附加任意类型的数据,避免了在JavaScript对象和DOM元素之间出现循环引用,以及由此而导致的内存泄漏. 数据缓存模块为DOM元素和JavaS ...

  8. vuex源码分析3.0.1(原创)

    前言 chapter1 store构造函数 1.constructor 2.get state和set state 3.commit 4.dispatch 5.subscribe和subscribeA ...

  9. VueX源码分析(5)

    VueX源码分析(5) 最终也是最重要的store.js,该文件主要涉及的内容如下: Store类 genericSubscribe函数 resetStore函数 resetStoreVM函数 ins ...

随机推荐

  1. 资源推荐:PPT快闪资源合集附配套字体下载

    样例ppt下载 搜索公众号“拒收”或扫码关注公众号 回复关键字“快闪ppt”获取全部福利 本公众号只出精品,拒收劣质 或者点击菜单链接获取获取全部资源

  2. git 创建分支 提交到远程分支

    git 创建分支 并 提交到远程分支 git branch 0.可以通过git branch -r 命令查看远端库的分支情况 1,从已有的分支创建新的分支(如从master分支),创建一个dev分支 ...

  3. 数据库——SQL-SERVER练习(5) 供应关系

    以下题目用到工程供应数据库关系模式:供应商(供应商号,供应商名,城市)        S(Sno,Sname,City)零件(零件号,零件名,零件颜色)     P(Pno,Pname,Color)工 ...

  4. C#数组3(可变数组)

    using System; namespace class1 { class program { static void Main(string[] args) { ][];//这里的行必须定义好,但 ...

  5. 往element 模块里面渲染数据

    <template> <div class="hello"> <section class="el-container"> ...

  6. [b0001] 伪分布式 hadoop 2.6.4

    说明: 任务:搭建Hadoop伪分布式版本. 目的:快速搭建一个学习环境,跳过这一环境,快速进入状态,使用Hadoop一些组件做些任务 没有选择2.7,觉得bug比较多,不稳定. 选择伪分布式简单快速 ...

  7. 生成前N个自然数随机置换的3个程序

    问题描述: 假设需要生成前N个自然数的一个随机置换.例如,{4,3,1,5,2}和{3,1,4,2,5}就是合法的置换,但{5,4,1,2,1}却不是,因为数1出现两次而数3却没有.这个程序常常用于模 ...

  8. svn 在Windows下用TortoiseSVN checkout 时报认证错误

    TortoiseSVN 第一次 checkout(检出)时,需要输入用户名密码,如果第一次你保存了你的用户名密码,那么这个检出的项目以后就会用这个用户名密码,如果你的密码改了之后,就会报一个认证错误的 ...

  9. httpd虚拟主机起不来!!

    前几天在公司,练习负载均衡配置.在配置虚拟主机的web服务(apache) ,创建好虚拟主机的配置文件 ss -tnl  查看监控端口80已起来,通过本地浏览器访问一直显示默认的欢迎页... 一个下午 ...

  10. luoguP4331 [BOI2004]Sequence 数字序列

    题意 大力猜结论. 首先将所有\(a_i\)变为\(a_i-i\),之后求不严格递增的\(b_i\),显然答案不变,最后\(b_i\)加上\(i\)即可. 考虑两种特殊情况: 1.\(a[]\)是递增 ...