李恒道 发表于 2022-1-19 22:17:50

Vuex源码makeLocalContext函数

# 前文

makeLocalContext函数主要用来做context的作用域处理

```javascript
function makeLocalContext (store, namespace, path) {
const noNamespace = namespace === ''

const local = {
    dispatch: noNamespace ? store.dispatch : (_type, _payload, _options) => {
      const args = unifyObjectStyle(_type, _payload, _options)
      const { payload, options } = args
      let { type } = args

      if (!options || !options.root) {
      type = namespace + type
      if (process.env.NODE_ENV !== 'production' && !store._actions) {
          console.error(` unknown local action type: ${args.type}, global type: ${type}`)
          return
      }
      }

      return store.dispatch(type, payload)
    },

    commit: noNamespace ? store.commit : (_type, _payload, _options) => {
      const args = unifyObjectStyle(_type, _payload, _options)
      const { payload, options } = args
      let { type } = args

      if (!options || !options.root) {
      type = namespace + type
      if (process.env.NODE_ENV !== 'production' && !store._mutations) {
          console.error(` unknown local mutation type: ${args.type}, global type: ${type}`)
          return
      }
      }

      store.commit(type, payload, options)
    }
}

// getters and state object must be gotten lazily
// because they will be changed by vm update
Object.defineProperties(local, {
    getters: {
      get: noNamespace
      ? () => store.getters
      : () => makeLocalGetters(store, namespace)
    },
    state: {
      get: () => getNestedState(store.state, path)
    }
})

return local
}
```

关于local的部分处理了dispatch以及commit函数的调用问题,对参数进行了一部分的处理,然后再加上namespace进行调用

主要部分在于

```
// getters and state object must be gotten lazily
// because they will be changed by vm update
Object.defineProperties(local, {
    getters: {
      get: noNamespace
      ? () => store.getters
      : () => makeLocalGetters(store, namespace)
    },
    state: {
      get: () => getNestedState(store.state, path)
    }
})
```

这里使用了Object.defineProperties对local的getters和state做了函数调用

一旦开始访问的时候则调用对应的函数,如果没有namespace则调用store.getters,如果有names则调用makelocalgetters或者getNestedState函数

注意,这里是一旦访问之后才会调用函数,在调用的时候已经初始化好了相关的各种数据以及变量,所以才可以调用,不是初始化的时候既进行调用的

```javascript
function makeLocalGetters (store, namespace) {
const gettersProxy = {}

const splitPos = namespace.length
Object.keys(store.getters).forEach(type => {
    // skip if the target getter is not match this namespace
    if (type.slice(0, splitPos) !== namespace) return

    // extract local getter type
    const localType = type.slice(splitPos)

    // Add a port to the getters proxy.
    // Define as getter property because
    // we do not want to evaluate the getters in this time.
    Object.defineProperty(gettersProxy, localType, {
      get: () => store.getters,
      enumerable: true
    })
})

return gettersProxy
}
```

这里的MakeLocalGetters通过遍历store.getters,判断是否存在对应的,如果存在则对gettersProxy设置上对应的名字,并设置一个Object.defineProptety响应式返回

然后返回gettersProxy对象

getNestedState与上函数基本等同

王一之 发表于 2022-1-20 09:17:14

看不懂了

李恒道 发表于 2022-1-20 10:21:16

王一之 发表于 2022-1-20 09:17
看不懂了

????这不是你指导我写的!
页: [1]
查看完整版本: Vuex源码makeLocalContext函数