This is the 8th day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021.

How does VUex attach to a Vue instance?

  function vuexInit () {
    const options = this.$options
    // store injection
    if (options.store) {
      this.$store = typeof options.store === 'function'
        ? options.store()
        : options.store
    } else if (options.parent && options.parent.$store) {
      this.$store = options.parent.$store
    }
  }
Copy the code

This article skips the VUE1-compliant approach, which overrides the internal _init method to inject $store when a VUE instance is initialized. The flow analysis of the above code is as follows:

  1. Get the $options property of the vue instance
  2. If options has a store property, inject the store on options into the vue instance. If this step is performed, this is the root instance of vUE and the mount point for the entire application. As you can see from the code, the store variable passed to the vue option can be a function that returns a store instance (new Vue({store}).mount('#app'))
  3. If Options has a parent instance, the parent’s store is injected into the subclass’s instance, indicating that it is not the root instance

The entire VUE application has only one store, and all vue instances share one store. The core idea of VUEX is single-state objects, which means predictable and controllable. There are strict rules for the operation of this single state object, which can only be changed in a specified way. Thanks to these strict rules, many advanced functions, such as time travel, can be implemented based on a unified gateway.

Vuex utility functions

In this section, we are only familiar with the utility functions in the util package. In the next section, we will examine store.js in detail. We don’t have to be fat.

find

export function find (list, f) {
  return list.filter(f)[0]}Copy the code

This function filters the list and returns the first element of the filtered list. Utah does not void the array, I guess because the list is recognized as an array. However, it is still recommended to short, change to the following form:

export function find (list = [], f) {
  return list && list.filter && list.filter(f)[0) | | {}}Copy the code

deepCopy

export function deepCopy (obj, cache = []) {
  if (obj === null || typeofobj ! = ='object') {
    return obj
  }
  const copy = Array.isArray(obj) ? [] : {}
  Object.keys(obj).forEach(key= > {
    copy[key] = deepCopy(obj[key], cache)
  })
  return copy
}
Copy the code

Deep copy function, code analysis is as follows:

  • The Typeof operator returns ‘object’ for instances of new operators other than primitives, arrays, and objects, and null returns object.
  • It can be seen that the copy objects of deep copy are mainly object objects and arrays.
  • Keys returns subscript arrays, which are called recursively to make a deep copy of an Object or array.

Each state change produces an immutable single state, and you can guess that the deep-copy function is used to maintain immutability.

forEachValue

export function forEachValue (obj, fn) {
  Object.keys(obj).forEach(key= > fn(obj[key], key))
}
Copy the code

Provides a general purpose traversal tool for objects and arrays. The first parameter is an object property or array element, and the second parameter is an object property name or array subscript.

isObject

export function isObject (obj) {
  returnobj ! = =null && typeof obj === 'object'
}
Copy the code

This method determines whether the parameter passed in is an object, as is an array. Redux will have an isPlainObject method that determines whether the incoming state is pure. This method also includes arrays, and we will look at how Utah operates on arrays in the following analysis.

partial

export function partial (fn, arg) {
  return function () {
    return fn(arg)
  }
}
Copy the code
  • Partial functions look like multiple functions at one time, but we can assume that the partial functions and arguments are wrapped as a function with no arguments for the convenience of calling, and the arguments are preserved through closures.
  • A closure is a function surrounded by an application, and a closure binds a function to its lexical context, that is, to its arG arguments,
  • This way arG parameters are not collected by the garbage collector.

The specific effects will be explained in detail in the next analysis of Store. To sum up:

  1. The object managed by VUex is an object or array, or object.
  2. This object is processed by deep-copy functions to maintain its immutability.
  3. A VUE application can only have one Store instance.
  4. Vuex is suitable for writing in terms of pure functions. For pure functions and side effects, check it out for yourself.

In a word, the more simple, the more controllable.