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