state也就是vuex里的值,也便是整个vuex的状态,而strict和state的设置有关,若是设置strict为true,那么不能直接修改state里的值,只能经过mutation来设置html
例1:vue
<!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>
渲染以下:vuex
当咱们在控制台修改store.state.coun里的值时页面会自动更新,例如:npm
此时页面自动更新了,变为了:数组
咱们设置一个strict属性看看:例2:app
<!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>
此时渲染以下:ide
当咱们在控制台输入store.state.count=2后,以下:函数
控制台报错了,页面渲染以下:源码分析
能够看到设置strict后,虽然能直接更改vuex里的值,可是会出现一条报错信息,即严格模式下vuex会给出一条提示,提示咱们只能经过mutation来修改。this
源码分析
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