博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vue状态管理插件Vuex源码探秘02
阅读量:7165 次
发布时间:2019-06-29

本文共 2363 字,大约阅读时间需要 7 分钟。

1.一个简单的用例

本文我们以一个Vuex的简单使用为例,探究Vuex的内部原理,首先上例子:

import Vuex from 'vuex'import Vue from 'vue'import {mapMutations,mapGetters} from 'vuex'Vue.use(Vuex)const state = {    name:'Quino'}const mutations = {    setName(state,payload){        state.name = payload    }}const getters = {    getName:state=>state.name}const store = new Vuex.Store{    state,    mutations,    getters}let vm = new Vue({    el,    store,    methods:{        ...mapMutations(['setName'])    },    computed:{        ...mapGetters(['getName'])    }})复制代码

先看一下mapMutations和mapGetters,这两个方法都来自src/helpers.js

export const mapMutations = normalizeNamespace((namespace, mutations) => {  const res = {}  normalizeMap(mutations).forEach(({ key, val }) => {    res[key] = function mappedMutation (...args) {      // Get the commit method from store      let commit = this.$store.commit      if (namespace) {        const module = getModuleByNamespace(this.$store, 'mapMutations', namespace)        if (!module) {          return        }        commit = module.context.commit      }      return typeof val === 'function'        ? val.apply(this, [commit].concat(args))        : commit.apply(this.$store, [val].concat(args))    }  })  return res})复制代码

其中normalizeNamespace定义在文件最下方,用于处理命名空间,由于我们没有使用命名空间,所以相当于直接用normalizeNamespace内的匿名函数参数直接处理我们的数组参数,此时namespace='',mutations=['setName']。

然后normalizeMap将mutations处理成[{key:'setName',val:'setName'}],normalizeMap目的是将我们的参数规范化,由其源码可知mapMutations的参数除了可以是数组外,还可以是对象,如下:

mapMutations({    setName:(commit,payload)=>{        commit('setName',payload)    }])复制代码

之后就按照mutations给局部变量res添加属性,最后返回了res,所以,我们上面的例子中,vm会得到一个这样的methods:

methods:{    setName:function mappedMutation(){        this.$store.commit('setName',payload);    }}复制代码

是不是和我们写的是一样的呢,只不过Vuex帮我们封装了这一步,使我们用起来更方便,可以像vm.setName('quino')这样直接使用,Vuex已经帮我们将内部的this绑定成了store。

同理,mapGetters会被处理成这样:

cmputed:{    getName:()={        return this.$store.getters['getName']    }}复制代码

同时getName的函数上还有一个vuex属性设置为true,用于和其他计算属性区分。

还记得前面总结的store的结构吗,这里的this.$store.getters其实会访问store._vm的computed属性。

2.操作store

这时如果我们调用vm.setName('www')会发生什么呢?

  • 首先会修改store内部的state属性
  • 因为这个属性被store内部的_vm的data属性引用,所以会触发响应式,使得_vm的计算属性重新计算。
  • 由于this.$store.getters访问的是_vm.computed,所以这也会触发我们例子中的实例vm的计算属性发生变化。
  • 由此,一个状态变化的侦测就完成了。

总结:Vuex还是利用了Vue响应式的特点来进行状态管理,在其内部定义了一个_vm用以管理我们的state。

后记:Vuex的源码探秘就到这里吧,对于Vuex的实现原理也掌握了个大概,但很多细节并没有去深究,以后需要的时候再回过头看看。

转载地址:http://evxwm.baihongyu.com/

你可能感兴趣的文章