Vue.js source code defines some tool methods, browser side, server side vue.js can share these methods
Vue 2.x
Based on the 2.6.14
-
Specific path: SRC \shared\util.js
-
Background: Build a type system based on flow
-
Objective: To help program generate better VM code in JS engine, conducive to performance optimization, improve efficiency
Type judgment
isUndef & isDef
Check whether the value is undefined or null
function isUndef (v) {
return v === undefined || v === null
}
function isDef (v) {
returnv ! = =undefined&& v ! = =null
}
Copy the code
isTrue & isFalse
Determine whether it is true or false
function isTrue (v) {
return v === true
}
function isFalse (v) {
return v === false
}
Copy the code
isPrimitive
Whether the data type is a base type (partial)
function isPrimitive (value) {
return (
typeof value === 'string' ||
typeof value === 'number' ||
typeof value === 'symbol' ||
typeof value === 'boolean')}Copy the code
Eg: SRC \core\vdom\create-element.js createElement
if (Array.isArray(data) || isPrimitive(data)) {/ /... }
Copy the code
isObject
Whether it is a reference type or a type constructed by new
This method is used in Vue for quick object checking: to identify an object from a known value when that value is of a type that conforms to JSON
function isObject (obj) {
returnobj ! = =null && typeof obj === 'object' // Note that null is in the typeof pit
}
Copy the code
isPromise
Is it a Promise function
function isPromise (val) {
return (
isDef(val) &&
typeof val.then === 'function' &&
typeof val.catch === 'function')}Copy the code
Eg: SRC \core\util\error. Js invokeWithErrorHandling for handling asynchronous exceptions
if(res && ! res._isVue && isPromise(res) && ! res._handled) {/ /... }
Copy the code
toRawType
Gets the string of the original type of the value
Based on the Object. The prototype. ToString. Call, in addition to the custom types, almost universal. Return: ‘[object, type]
var _toString = Object.prototype.toString;
function toRawType (value) {
return _toString.call(value).slice(8, -1)}Copy the code
Eg: SRC \core\util\options.js normalizeProps, normalizing the props property
// The props property type does not meet the requirements
warn(
`Invalid value for option "props": expected an Array or an Object, ` +
`but got ${toRawType(props)}. `,
vm
)
Copy the code
hasOwnProperty
Checks whether the object has the specified attribute
var hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn (obj, key) {
return hasOwnProperty.call(obj, key)
}
Copy the code
Data conversion
toNumber
Convert to numbers
// Convert the value to a number. If the conversion fails, return the original string
function toNumber (val) {
var n = parseFloat(val);
return isNaN(n) ? val : n
}
Copy the code
toString
Convert to string
function toString (val) {
return val == null
? ' '
: Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
? JSON.stringify(val, null.2) // For arrays or objects
: String(val)
}
Copy the code
Json.stringify (value[, replacer [, space]]);
toArray
Convert an array-like object to an array
function toArray (list, start) {
start = start || 0;
var i = list.length - start;
var ret = new Array(i);
while (i--) {
ret[i] = list[i + start];
}
return ret
}
Copy the code
Eg: SRC \core\global-api\use.js initUse
const args = toArray(arguments.1) // arguments can understand the array object of the arguments passed to the function
Copy the code
To convert an array-like object to an array, use the following methods:
(1) Array. The prototype. Slice. The call
(2) Array. The from ()
toObject
Merges an array of objects into an object
// Assign attributes to the target object
function extend (to, _from) {
for (var key in _from) {
to[key] = _from[key];
}
return to
}
function toObject (arr) {
var res = {};
for (var i = 0; i < arr.length; i++) {
if(arr[i]) { extend(res, arr[i]); }}return res
}
Copy the code
Eg: SRC \platforms\weex\ Runtime \modules\style.js updateStyle
if (Array.isArray(style)) {
style = vnode.data.style = toObject(style)
}
Copy the code
It is known that v-bind:style’s array syntax can apply multiple style objects to the same element
capitalize
Uppercase
// cached method below
var capitalize = cached(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)});Copy the code
hyphenate
Camelback shortened horizontal line separation
var hyphenateRE = /\B([A-Z])/g;
var hyphenate = cached(function (str) {
return str.replace(hyphenateRE, '- $1').toLowerCase()
});
Copy the code
camelize
The short horizontal line is changed to hump
var camelizeRE = /-(\w)/g;
var camelize = cached(function (str) {
return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ' '; })});Copy the code
Cache data
cached
The pass is a function and the return is a function that is used to cache the function created. The capitalize, hyphenate, and capitalize described above all use the cached method
Why do you do that? Especially great ingenuity: conducive to performance optimization.
For details: Portal 1 Portal 2
function cached (fn) {
var cache = Object.create(null);
return (function cachedFn (str) {
var hit = cache[str]; // Cache
return hit || (cache[str] = fn(str))
})
}
Copy the code
makeMap
Define a set of data that can be used to determine whether or not it is a built-in HTML tag
/ * * *@description:
* @param STR The character string *@param ExpectsLowerCase whether lowercase * is required@return {*}* /
function makeMap (str, expectsLowerCase) {
var map = Object.create(null);
var list = str.split(', ');
for (var i = 0; i < list.length; i++) {
map[list[i]] = true;
}
return expectsLowerCase
? function (val) { return map[val.toLowerCase()]; }
: function (val) { returnmap[val]; }}Copy the code
Eg: SRC \platforms\web\util\element.js isHTMLTag
var isHTMLTag = makeMap(
'html,body,base,head,link,meta,style,title,' +
'... ' +
'content,element,shadow,template,blockquote,iframe,tfoot'
)
isHTMLTag('iframe') // true
Copy the code
Determines whether objects are equal
looseEqual
The overall idea: first type judgment, and then recursive call
function looseEqual (a, b) {
// a, b are equal to, return true
if (a === b) { return true }
var isObjectA = isObject(a);
var isObjectB = isObject(b);
// Determine if it is an object (reference type)
if (isObjectA && isObjectB) {
try {
var isArrayA = Array.isArray(a);
var isArrayB = Array.isArray(b);
if (isArrayA && isArrayB) {
If the length of each item is the same, return false if the length is not the same
return a.length === b.length && a.every(function (e, i) {
return looseEqual(e, b[i])
})
} else if (a instanceof Date && b instanceof Date) {
// If the two types are Date, use the timestamp to check
return a.getTime() === b.getTime()
} else if(! isArrayA && ! isArrayB) {If the length of each attribute is the same, return false if the length is not the same
var keysA = Object.keys(a);
var keysB = Object.keys(b);
return keysA.length === keysB.length && keysA.every(function (key) {
return looseEqual(a[key], b[key])
})
} else {
/* istanbul ignore next */
return false}}catch (e) {
/* istanbul ignore next */
return false}}else if(! isObjectA && ! isObjectB) {// If neither is an object (reference type), convert it to a string comparison
return String(a) === String(b)
} else {
return false}}Copy the code
other
remove
Delete an array item
function remove (arr, item) {
if (arr.length) {
var index = arr.indexOf(item);
if (index > -1) {
return arr.splice(index, 1)}}}Copy the code
once
The function is executed only once
function once (fn) {
var called = false;
return function () {
if(! called) { called =true;
fn.apply(this.arguments); }}}Copy the code
Vue 3.x
Based on the 3.2.6
-
Source link
-
Background: Type validation is based on TypeScript, and instead of flow, we have to mention Vue2. X’s compelling comments
// src\core\instance\lifecycle.js
const propOptions: any = vm.$options.props // wtf flow?
// src\platforms\web\server\modules\dom-props.js
// $flow-disable-line (WTF?)
const attr = propsToAttrMap[key] || key.toLowerCase()
Copy the code
TypeScript vs Flow, what a nice follow-up to TypeScript. Portals
Reserve & Supplement
-
CacheStringFunction: Reserved, that is, cached
-
MakeMap: keep
-
LooseEqual: Retain, rewrite optimization, supplement looseCompareArrays method, compare whether two arrays are equal or not
// source code: packages shared SRC looseequal.ts
function looseCompareArrays(a, b) {
// If the length is inconsistent, return false
if(a.length ! == b.length)return false;
let equal = true;
// If the length is the same, compare each item
for (let i = 0; equal && i < a.length; i++) {
equal = looseEqual(a[i], b[i]);
}
return equal;
}
Copy the code
-
Data conversion
-
Remove toArray and toObject
The toArray with Array. Prototype. Slice. Call and Array from instead
-
Added toTypeString, object to string
const objectToString = Object.prototype.toString; const toTypeString = (value) = > objectToString.call(value); toTypeString({num: 0}) // "[object Object]" Copy the code
-
-
Type judgment: supplementary adjustment, more detailed
const isArray = Array.isArray;
const isMap = (val) = > toTypeString(val) === '[object Map]';
const isSet = (val) = > toTypeString(val) === '[object Set]';
const isDate = (val) = > val instanceof Date;
const isFunction = (val) = > typeof val === 'function';
const isString = (val) = > typeof val === 'string';
const isSymbol = (val) = > typeof val === 'symbol';
const isObject = (val) = >val ! = =null && typeof val === 'object';
const isPromise = (val) = > {
return isObject(val) && isFunction(val.then) && isFunction(val.catch);
};
/ /...
Copy the code
new
getGlobalThis
Gets the global this to the object
let _globalThis;
const getGlobalThis = () = > {
// If _globalThis is already defined (executed method), it is returned without further judgment
return (_globalThis ||
(_globalThis =
typeofglobalThis ! = ='undefined'
? globalThis
: typeofself ! = ='undefined'
? self
: typeof window! = ='undefined'
? window
: typeof global! = ='undefined'
? global
: {}));
};
Copy the code
def
Defining object properties
const def = (obj, key, value) = > {
Object.defineProperty(obj, key, {
configurable: true.// It is configurable
enumerable: false.// not enumerable
value
});
};
Copy the code
isModelListener
Checks whether the current string starts with onUpdate:
const isModelListener = (key) = > key.startsWith('onUpdate:');
Copy the code
String. The prototype. The startsWith (searchString [position]) : returns a Boolean value that indicates whether the parameter String in the head of the original String.
isIntegerKey
Checks whether the value is an integer key
const isIntegerKey = (key) = >isString(key) && key ! = ='NaN' &&
key[0]! = =The '-' &&
' ' + parseInt(key, 10) === key;
Copy the code
invokeArrayFns
FNS is an array, each element is a function, traversal number group execution, facilitate the execution of multiple functions at one time
const invokeArrayFns = (fns, arg) = > {
for (let i = 0; i < fns.length; i++) { fns[i](arg); }};Copy the code
hasChanged
Comparing two values for equality, using object. is, behaves essentially the same as the strict comparison operator (===), but note:
- Plus 0 is not equal to minus 0
- NaN equals itself
const hasChanged = (value, oldValue) = > !Object.is(value, oldValue);
hasChanged(+0, -0) // true
hasChanged(NaN.NaN) // false
Copy the code
Link drive door
JSON.stringify
Class is bound to Style
Object.is
Last but not least
If there is anything wrong, please give me your advice