1.Vue.util 1 2 3 4 5 6 Vue.util = { warn, extend, mergeOptions, defineReactive, };
Vue.util是Vue内部的工具方法,不推荐业务组件去使用,因为可能随着版本发生变动,不开发第三方Vue插件会比较少用
2.Vue.set/Vue.delete 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 export function set(target: Array<any> | Object, key: any, val: any): any { // 如果是数组 直接调用我们重写的splice方法 可以刷新视图 if (Array.isArray(target) && isValidArrayIndex(key)) { target.length = Math.max(target.length, key); target.splice(key, 1, val); return val; } // 如果是对象本身的属性,则直接添加即可 if (key in target && !(key in Object.prototype)) { target[key] = val; return val; } const ob = (target: any).__ob__; // 如果对象本身就不是响应式 不需要将其定义成响应式属性 if (!ob) { target[key] = val; return val; } // 利用defineReactive 实际就是Object.defineProperty 将新增的属性定义成响应式的 defineReactive(ob.value, key, val); ob.dep.notify(); // 通知视图更新 return val; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 export function del(target: Array<any> | Object, key: any) { // 如果是数组依旧调用splice方法 if (Array.isArray(target) && isValidArrayIndex(key)) { target.splice(key, 1); return; } const ob = (target: any).__ob__; // 如果对象本身就没有这个属性 什么都不做 if (!hasOwn(target, key)) { return; } // 直接使用delete 删除这个属性 delete target[key]; // 如果对象本身就不是响应式 直接返回 if (!ob) { return; } ob.dep.notify(); //通知视图更新 }
该API在业务场经常使用与新增或删除响应式数据,由于Object.defineProperty对于数组和对象的响应式没有具体的劫持,所以通过该API操作会直接触发渲染
3.Vue.nextTick 该函数为异步更新的核心,通过将函数放入执行栈当中,再分别使用promise、mutationObserver、setImmediate和setTimeout来进行一个微任务后执行的异步机制,常用于要获取dom节点相关属性时
4.Vue.observable 1 2 3 4 Vue.observable = <T>(obj: T): T => { observe(obj); return obj; };
核心方法就是调用observe方法将传入的数据变成响应式对象,用于制造全局变量在组件中共享数据
5.Vue.options 1 2 3 4 5 6 7 8 9 10 Vue.options = Object.create(null); ASSET_TYPES.forEach((type) => { Vue.options[type + "s"] = Object.create(null); }); // this is used to identify the "base" constructor to extend all plain-object // components with in Weex's multi-instance scenarios. Vue.options._base = Vue; extend(Vue.options.components, builtInComponents); //内置组件
options是存放组件、指令和过滤器的容器,Vue.options._base指向Vue构造函数
6.Vue.use 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Vue.use = function (plugin: Function | Object) { const installedPlugins = this._installedPlugins || (this._installedPlugins = []); if (installedPlugins.indexOf(plugin) > -1) { // 如果安装过这个插件直接返回 return this; } const args = toArray(arguments, 1); // 获取参数 args.unshift(this); //在参数中增加Vue构造函数 if (typeof plugin.install === "function") { plugin.install.apply(plugin, args); // 执行install方法 } else if (typeof plugin === "function") { plugin.apply(null, args); // 没有install方法直接把传入的插件执行 } // 记录安装的插件 installedPlugins.push(plugin); return this; };
主要用于插件的注册,调用插件的install方法,把自身Vue传到插件的install方法,可以避免第三方插件强依赖Vue
7.Vue.mixin 调用mergeOptions合并选项,然后合并字段。 全局混入方法,一般作用提取全局的公共方法和属性 8.Vue.extend 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Vue.extend = function (extendOptions: Object): Function { const Sub = function VueComponent(options) { // 创建子类的构造函数 并且调用初始化方法 this._init(options); }; Sub.prototype = Object.create(Super.prototype); // 子类原型指向父类 Sub.prototype.constructor = Sub; //constructor指向自己 Sub.options = mergeOptions( //合并自己的options和父类的options Super.options, extendOptions ); return Sub; };
组件构造器Vue的组件创建,利用原型继承的方法创建继承自Vue的子类
9.组件、指令、过滤器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 export function initAssetRegisters(Vue: GlobalAPI) { var ASSET_TYPES = ["component", "directive", "filter"]; /** * Create asset registration methods. */ ASSET_TYPES.forEach((type) => { Vue[type] = function ( id: string, definition: Function | Object ): Function | Object | void { if (!definition) { return this.options[type + "s"][id]; } else { if (type === "component" && isPlainObject(definition)) { definition.name = definition.name || id; definition = this.options._base.extend(definition); } if (type === "directive" && typeof definition === "function") { definition = { bind: definition, update: definition }; } this.options[type + "s"][id] = definition; //把组件 指令 过滤器 放到Vue.options中 return definition; } }; }); }
定义component、directive、filter三大api并且格式化用户传入内容,最后把结果放到options中
10.小结 如上,都是在initGlobalAPI时将API挂载到Vue构造函数当中,可以在Vue全局中使用