经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
vuex源码分析(二) state及strict属性 详解
来源:cnblogs  作者:大沙漠  时间:2019/9/10 10:53:43  对本文有异议

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

例1:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  7. <script src="https://unpkg.com/vuex@3.1.0/dist/vuex.js"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <p>count:{{count}}</p>
  12. </div>
  13. <script>
  14. const store = new Vuex.Store({
  15. state:{count:1}
  16. })
  17. var app = new Vue({
  18. el:"#app",
  19. store,
  20. computed:{
  21. count(){return store.state.count }
  22. }
  23. })
  24. </script>
  25. </body>
  26. </html>

渲染如下:

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

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

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

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  7. <script src="https://unpkg.com/vuex@3.1.0/dist/vuex.js"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <p>count:{{count}}</p>
  12. </div>
  13. <script>
  14. const store = new Vuex.Store({
  15. state:{count:1},
  16. strict:true //新增一个strict属性,值为true
  17. })
  18. var app = new Vue({
  19. el:"#app",
  20. store,
  21. computed:{
  22. count(){return store.state.count }
  23. }
  24. })
  25. </script>
  26. </body>
  27. </html>

此时渲染如下:

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

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

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

 

源码分析


writer by:大沙漠 QQ:22969969

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

  1. function resetStoreVM (store, state, hot) { //重新存储数据
  2. var oldVm = store._vm;
  3. // bind store public getters
  4. store.getters = {}; //给store定义一个getters属性,值为一个对象
  5. var wrappedGetters = store._wrappedGetters; //获取store的所有getter数组信息
  6. var computed = {};
  7. forEachValue(wrappedGetters, function (fn, key) { //遍历wrappedGetters
  8. // use computed to leverage its lazy-caching mechanism
  9. computed[key] = function () { return fn(store); }; //将getter保存到computed里面
  10. Object.defineProperty(store.getters, key, { //设置store.getters的key的访问器属性
  11. get: function () { return store._vm[key]; },
  12. enumerable: true // for local getters
  13. });
  14. });
  15. // use a Vue instance to store the state tree
  16. // suppress warnings just in case the user has added
  17. // some funky global mixins
  18. var silent = Vue.config.silent; //保存Vue.config.silent的配置
  19. Vue.config.silent = true; //设置Vue.config.silent配置属性为true(先关闭警告)
  20. store._vm = new Vue({ //创建new Vue()实例把$$state和computed变成响应式的
  21. data: {
  22. $$state: state
  23. },
  24. computed: computed
  25. });
  26. Vue.config.silent = silent; //将Vue.config.silent复原回去
  27.  
  28. // enable strict mode for new vm
  29. if (store.strict) { //初始化Strore时,如果给strict传入了true
  30. enableStrictMode(store); //则调用enableStrictMode()函数
  31. }
  32. if (oldVm) {
  33. if (hot) {
  34. // dispatch changes in all subscribed watchers
  35. // to force getter re-evaluation for hot reloading.
  36. store._withCommit(function () {
  37. oldVm._data.$$state = null;
  38. });
  39. }
  40. Vue.nextTick(function () { return oldVm.$destroy(); });
  41. }
  42. }

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

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

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

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

原文链接:http://www.cnblogs.com/greatdesert/p/11423783.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号