A brief analysis of the source code content of VueX
Vuex is a state management pattern developed specifically for Vue.js applications. For single-page applications with many components and complex interactions, Vuex provides a convenient, accurate and predictable state management method to facilitate data sharing and modification between components.
The file structure is as follows
/module
/plugins
helpers.js
##index.esm.js
index.js
store.js
util.js
find function
/** * Get the first item that pass the test * by second argument function * * @param {Array} list * @param {Function} f * @return {*} */ export function find (list, f) { return list.filter(f)[0] }
it('find', () => { const list = [33, 22, 112, 222, 43] expect(find(list, function (a) { return a % 2 === 0 })).toEqual(22) })
- ##Use first
- Assertion function f
Filters
list list
, and finally takes the first element of the filtered list.
/**
* Deep copy the given object considering circular structure.
* This function caches all nested objects and its copies.
* If it detects circular structure, use cached copy to avoid infinite loop.
*
* @param {*} obj
* @param {Array<Object>} cache
* @return {*}
*/
export function deepCopy (obj, cache = []) {
// just return if obj is immutable value
if (obj === null || typeof obj !== 'object') {
return obj
}
// if obj is hit, it is in circular structure
const hit = find(cache, c => c.original === obj)
if (hit) {
return hit.copy
}
const copy = Array.isArray(obj) ? [] : {}
// put the copy into cache at first
// because we want to refer it in recursive deepCopy
cache.push({
original: obj,
copy
})
Object.keys(obj).forEach(key => {
copy[key] = deepCopy(obj[key], cache)
})
return copy
}
// 普通结构 it('deepCopy: nornal structure', () => { const original = { a: 1, b: 'string', c: true, d: null, e: undefined } const copy = deepCopy(original) expect(copy).toEqual(original) }) // 嵌套结构 it('deepCopy: nested structure', () => { const original = { a: { b: 1, c: [2, 3, { d: 4 }] } } const copy = deepCopy(original) expect(copy).toEqual(original) }) // 循环引用结构 it('deepCopy: circular structure', () => { const original = { a: 1 } original.circular = original const copy = deepCopy(original) expect(copy).toEqual(original) })
Analysis:
- Function: Deep cloning function that supports circular references
- The first if judgment
- obj === null || typeof obj !== 'object'
Judgment If it is not a reference type and is returned directly (the basic type is a value copy), it is also an exit from recursion.
The second judgment - hit
is to judge whether it is a circular reference. Since it is a circular reference, there should be a copy cached in the cache, directly Get it from the cache to avoid making a duplicate copy again.
What is a circular reference? See the third test case - original.circular = original
. The circular reference and the referenced content are the same. Caching is used to avoid duplication. Clone (the content is the same)
- original.circular
is a circular reference,
original
is a circular reference First put - cope
into
cache
. When recursing, if you encounter a circular reference, make sure there is a copy of thecircularly referenced copy in the cache.
, butcopy
must be a reference type. Why - cope
must be a reference type?
SoCircular reference
What is saved is the reference, not the content (the copy has not been completed at this time). The copy is not completed during the recursion. The copy is completed only after the recursion is completed, so thatwill be circularly referenced in the future## When the content of # changes (copying is completed), the content of
circular referencechanges simultaneously
const copy = Array.isArray(obj) ? [] : {} - must be a reference type.
Finally Object.keys - You can traverse all key names of objects and arrays (only the properties of the instance are returned, excluding the prototype chain and Symbol) to implement recursive cloning.
There are two exits, one is a basic type and the other is a circular reference. - ##forEachValue
/** * forEach for object */ export function forEachValue (obj, fn) { Object.keys(obj).forEach(key => fn(obj[key], key)) }
Test case it('forEachValue', () => {
let number = 1
function plus (value, key) {
number += value
}
const origin = {
a: 1,
b: 3
}
forEachValue(origin, plus)
expect(number).toEqual(5)
})
A Function that traverses objects (supports objects and arrays)
- fn(value, key) But the first parameter of the callback function is the value, and the second parameter is the key Value
isObject
export function isObject (obj) { return obj !== null && typeof obj === 'object' }
Test Case it('isObject', () => {
expect(isObject(1)).toBe(false)
expect(isObject('String')).toBe(false)
expect(isObject(undefined)).toBe(false)
expect(isObject({})).toBe(true)
expect(isObject(null)).toBe(false)
expect(isObject([])).toBe(true)
expect(isObject(new Function())).toBe(false)
})
Determine whether it is an object. There is no judgment here whether it is a native object. Arrays also pass.
Because typeof null === 'object' must first determine whether it is null
##isPromise
export function isPromise (val) { return val && typeof val.then === 'function' }
it('isPromise', () => { const promise = new Promise(() => {}, () => {}) expect(isPromise(1)).toBe(false) expect(isPromise(promise)).toBe(true) expect(isPromise(new Function())).toBe(false) })
- First determine whether val is not undefined, and then You can judge val.then to avoid reporting errors
- The basis for judgment is whether val.then is a function
assert
export function assert (condition, msg) { if (!condition) throw new Error(`[vuex] ${msg}`) }
it('assert', () => { expect(assert.bind(null, false, 'Hello')).toThrowError('[vuex] Hello') })
index.js
and index.esm.js
index.js
import { Store, install } from './store'
import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers'
export default {
Store,
install,
version: '__VERSION__',
mapState,
mapMutations,
mapGetters,
mapActions,
createNamespacedHelpers
}
Copy after login
import { Store, install } from './store' import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' export default { Store, install, version: '__VERSION__', mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers }
index.esm.js
import { Store, install } from './store' import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' export default { Store, install, version: '__VERSION__', mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } export { Store, install, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers }
index.esm.js
is better than- index. js
- There is an additional import mode
: There are two ways to importimport Vuex, { mapState } from 'index.esm.js'
: There is only one way to importimport Vuex from 'index.js'
##mixin.js
in options<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>export default function (Vue) { const version = Number(Vue.version.split(&#39;.&#39;)[0]) if (version >= 2) { Vue.mixin({ beforeCreate: vuexInit }) } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. const _init = Vue.prototype._init Vue.prototype._init = function (options = {}) { options.init = options.init ? [vuexInit].concat(options.init) : vuexInit _init.call(this, options) } } /** * Vuex init hook, injected into each instances init hooks list. */ function vuexInit () { const options = this.$options // store injection if (options.store) { this.$store = typeof options.store === &#39;function&#39; ? options.store() : options.store } else if (options.parent && options.parent.$store) { this.$store = options.parent.$store } } }</pre><div class="contentsignin">Copy after login</div></div>Analysis: </p> <h4 id="Why-every-component-has">Why every component has </h4>\(store attribute, that is, every component can get\)<p>store</p> <ul class=" list-paddingleft-2"> <li><p>Vue2 directly uses the mixin and hook function beforeCreate, and Vue1 uses the appearance (decorator) mode to rewrite the Vue._init function. <span class="math inline"></span></p></li> <li>vuexInit<p> is to inject the globally registered store into the current component, before creating the component</p> </li> <li> <p><code>\(options are options of `new Vue(options)`,\)
There is storeSince
beforeCreate
is the cycle hook ofVue
,this
points to the current component instance, sothis.$store
The store can be directly injected into the current component-
All components are inherited from a global Vue, the global mixin component cycle hook
beforeCreate
, so that each component Can be automatically injected into the store, that is, each component can get the global Vuenew Vue({ el: 'app', store, router })
directly through$store
#store
Related recommendations:
Talk about me Understanding of vuex
Vue.js-vuex (state management)
The above is the detailed content of A brief analysis of the source code content of VueX. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Article discusses creating, publishing, and maintaining JavaScript libraries, focusing on planning, development, testing, documentation, and promotion strategies.

The article discusses strategies for optimizing JavaScript performance in browsers, focusing on reducing execution time and minimizing impact on page load speed.

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

The article discusses effective JavaScript debugging using browser developer tools, focusing on setting breakpoints, using the console, and analyzing performance.

The article explains how to use source maps to debug minified JavaScript by mapping it back to the original code. It discusses enabling source maps, setting breakpoints, and using tools like Chrome DevTools and Webpack.

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

This tutorial will explain how to create pie, ring, and bubble charts using Chart.js. Previously, we have learned four chart types of Chart.js: line chart and bar chart (tutorial 2), as well as radar chart and polar region chart (tutorial 3). Create pie and ring charts Pie charts and ring charts are ideal for showing the proportions of a whole that is divided into different parts. For example, a pie chart can be used to show the percentage of male lions, female lions and young lions in a safari, or the percentage of votes that different candidates receive in the election. Pie charts are only suitable for comparing single parameters or datasets. It should be noted that the pie chart cannot draw entities with zero value because the angle of the fan in the pie chart depends on the numerical size of the data point. This means any entity with zero proportion

Once you have mastered the entry-level TypeScript tutorial, you should be able to write your own code in an IDE that supports TypeScript and compile it into JavaScript. This tutorial will dive into various data types in TypeScript. JavaScript has seven data types: Null, Undefined, Boolean, Number, String, Symbol (introduced by ES6) and Object. TypeScript defines more types on this basis, and this tutorial will cover all of them in detail. Null data type Like JavaScript, null in TypeScript
