This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
1. Introduction
Official documentation analysis of Vue source code, always encounter these global API calls, so first analyze it.
A global API is a static method mounted on a Vue, roughly as follows
- Set adds or modifies the value of an attribute of an object such that
property
It is also reactive and triggers view updates - Delete Deletes an attribute of an object and triggers an update
- NextTick puts the callbacks together in an array, next one
tick
To call back one by one in the order in which they are added - Observable makes an object reactive
- Use registered plug-in
- Mixin options
- The extend to generate
Vue
A subclass
The remaining three ‘components ‘, ‘directive’, and ‘filter’ are dedicated to articles
2. set
The official documentation
This method is mounted on both the static and instance Vue
/ / static
Vue.set = set
/ / instance
Vue.prototype.$set = set
Copy the code
//
/** * Set a property on an object. Adds the new property and * triggers change notification if the property doesn't * already exist. */
export function set(
target: Array<any> | Record<string.any>,
key: any,
val: any
) :any {
// Set the array index value
if (Array.isArray(target) && isValidArrayIndex(key)) {
// Index may be set to be greater than the length of the array
target.length = Math.max(target.length, key)
// The array's splice method can listen for changes
target.splice(key, 1, val)
return val
}
if (key intarget && ! (keyin Object.prototype)) {
// If key is an inherent property of target, it can be assigned directly because target is reactive
target[key] = val
return val
}
const ob = (target as any).__ob__
if(! ob) {// Target is not a reactive value
target[key] = val
return val
}
// make val responsive
defineReactive(ob.value, key, val)
// Target triggers a notification
ob.dep.notify()
return val
}
Copy the code
Summary: It is used to assign a value to an object’s properties, triggering its update notification if the object is responsive
Note: We cannot assign values to Vue instances or $data. For stability, we cannot assign values to Vue instances or $data
3. delete
The official documentation
This method is mounted on both the static and instance Vue
/ / static
Vue.delete = del
/ / instance
Vue.prototype.$delete = del
Copy the code
/** * Delete a property and trigger change if necessary. */
export function del(target: Array<any> | Object, key: any) {
if (Array.isArray(target) && isValidArrayIndex(key)) {
// The array method is deleted, and the modification triggers the update
target.splice(key, 1)
return
}
const ob = (target as any).__ob__
if(! hasOwn(target, key)) {// The deleted attribute does not exist
return
}
delete target[key]
if(! ob) {// The object with the deleted attribute is not responsive
return
}
// If it is reactive, trigger an update
ob.dep.notify()
}
Copy the code
Summary: It is used to remove the properties of an object and trigger its update notification if the object is responsive
Note: You cannot delete Vue instance attributes or $data attributes. For stability, you cannot delete application exceptions
4. nextTick
See my previous article
5. extend
The official documentation
This method is only mounted on Vue static
/** * Using the base Vue constructor, create a "subclass". This is not strictly a subclass, as it is not inherited from *@param ExtendOptions Extended component Options *@returns Return the extended subclass */
Vue.extend = function (extendOptions: any) :Component {
extendOptions = extendOptions || {}
const Super = this
const SuperId = Super.cid
// Cache the extended subclass on the extended object. If you extend the same object on the same parent class, you can use cache
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
const name = extendOptions.name || Super.options.name
// Define a subclass, which will be returned
const Sub = (function VueComponent(this: any, options: any) {
this._init(options)
} as unknown) as Component
// If the parent class is inherited in this way, modifying the parent class does not affect the parent class. Modifying the parent class does affect the lookup of the child class's prototype methods
Sub.prototype = Object.create(Super.prototype)
// fix constructor to point otherwise to the parent class
Sub.prototype.constructor = Sub
// Every Vue class (subclass) has a CID that identifies uniqueness. The CID of a Vue is 0, and the subclass is incremented
Sub.cid = cid++
// merge options from the parent class into subclasses
Sub.options = mergeOptions(Super.options, extendOptions)
/ / specify the parent class, in only one place USES, resolveConstructorOptions _init
Sub['super'] = Super
// For props and computed properties, we define the proxy getters on
// the Vue instances at extension time, on the extended prototype. This
// avoids Object.defineProperty calls for each instance created.
if (Sub.options.props) {
initProps(Sub)
}
if (Sub.options.computed) {
initComputed(Sub)
}
// allow further extension/mixin/plugin usage
// Subclasses can extend subclasses
Sub.extend = Super.extend
Sub.mixin = Super.mixin
Sub.use = Super.use
// create asset registers, so extended classes
// can have their private assets too.
ASSET_TYPES.forEach(function (type) {
Sub[type] = Super[type]})// enable recursive self-lookup
if (name) {
Sub.options.components[name] = Sub
}
// keep a reference to the super options at extension time.
// later at instantiation we can check if Super's options have
// been updated.
Sub.superOptions = Super.options
Sub.extendOptions = extendOptions
Sub.sealedOptions = extend({}, Sub.options)
// cache constructor
// Cache this subclass
cachedCtors[SuperId] = Sub
return Sub
}
Copy the code
Summary: To extend the subclass, all custom components are obtained through this method
When you analyze components in the future, you can go further
6. use
The official documentation
This method is only mounted on Vue static
Vue.use = function (plugin: Function | any) {
// Read cache
const installedPlugins =
this._installedPlugins || (this._installedPlugins = [])
// If the plugin has been installed in the cache, return it directly
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
// 得到 [this, ...arguments]
const args = toArray(arguments.1)
args.unshift(this)
// When the plug-in executes, the first argument is Vue, and the rest is passed in when the plug-in is installed
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
// Cache the plug-in
installedPlugins.push(plugin)
return this
}
Copy the code
There are no plug-ins installed inside the Vue code
We can package any enhancements to Vue as “plug-ins “.
7. mixin
The official documentation
Register a global blend, the code is extremely simple
Vue.mixin = function (mixin: Object) {
// Merge incoming mixins into options
this.options = mergeOptions(this.options, mixin)
return this
}
Copy the code
There are no options mixed into the code inside Vue
8. compile
The official documentation
Compile the template string into the render function
Vue.compile = compileToFunctions
Copy the code
It’s a big hole. I’ll write about it later
9. observable
The official documentation
To make an object reactive
Vue.observable = <T>(obj: T): T= > {
observe(obj)
return obj
}
Copy the code
So a responsive object, which is reading its properties is known to it, and when its properties change, it tells it where it’s reading its properties, and if that place needs to be, you can do something, like in render, it rerenders, in computed, it recalculates, In Watch, the function will be triggered to execute again. These three places are the only ones that are not needed. In Vue, the dep. target is used to mark whether there is a need.
Leave a hole here, too
10. The last
This is just the first glimpse of the static methods on Vue, leaving three (five) holes that will be filled in later.
Attached are several articles I wrote earlier
- Vue2 source code analysis nextTick
- Code snippet JS flow limiting scheduler
- Linked Lists of Data Structures and Algorithms (1)
- Vue2 source code parsing event system $on