Vuex getters源码分析

目录

一.简介

 二.源码


一.简介

Vuex允许我们在store中定义"getter"(可以认为是store的计算属性),就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算每个getter对应的匿名函数可以带四个参数,分别是当前模块的state、getter和根模块的state、getter,例如:

<div id="app">
    <p>{{reverseMessage}}</p>
</div>
<script>
    const store = new Vuex.Store({
        state:{reverseMessage:'Hello Vue!'},
        getters:{
            reverseMessage:function(state){return state.reverseMessage.split('').reverse().join('');}
        }
    })
    new Vue({
        el:'#app',
        store,
        computed:{
            reverseMessage:function(){return this.$store.getters.reverseMessage}
        }
    })
</script>

 二.源码

在创建Vuex.Store()初始化时执行installModule()安装根模块,与getter相关的如下:

function installModule(store, rootState, path, module, hot) {  //安装模块
  /*略*/
  module.forEachGetter(function (getter, key) {  //遍历module模块的getters对象,如果找到了,则执行这个匿名函数 参数1:每个getter值 key:对应的键名
    var namespacedType = namespace + key; //拼凑命名空间+键名,例如:a/computedCount
    registerGetter(store, namespacedType, getter, local); //依次执行registerGetter
  });
  /*略*/
}

registerGetter用于注册每个getter,如下:

function registerGetter(store, type, rawGetter, local) {
  //注册getter
  if (store._wrappedGetters[type]) {
    //如果store._wrappedGetters下已经有key了
    {
      console.error("[vuex] duplicate getter key: " + type); //报错,即不允许重复
    }
    return;
  }
  store._wrappedGetters[type] = function wrappedGetter(store) {
    //保存到store._wrappedGetters对应的type里
    return rawGetter(
      //执行store函数 四个参数分别为local state、local getters、root state、root getters
      local.state, // local state
      local.getters, // local getters
      store.state, // root state
      store.getters // root getters
    );
  };
}

这样在 store._wrappedGetters中就存储了对应的getter,getter是一个匿名函数,函数有一个参数是store,为vuex.store()的实例,创建vue实例时会将其传入,这样在geter里就能访问到根模块的state和getters了

Vuex到resetStoreVM()创建Vue实例时,与getter有关的逻辑如下:

function resetStoreVM(store, state, hot) {
  //重新存储数据
  var oldVm = store._vm;

  // bind store public 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);
    }; //将computed[key]定义为一个函数表达式,内部返回fn()执行后的结果,传入store参数,这样在geter里就能访问到根模块的state和getters了
    Object.defineProperty(store.getters, key, {
      //设置store.getters的key的访问器属性,这样就可以通过store.getters.aaa访问到某个具体的值了
      get: function () {
        return store._vm[key];
      },
      enumerable: true, // for local getters
    });
  });

  /*略*/
}

state内信息被修改,getter内信息会自动更新,是由于Vue的响应式设计

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值