全局 API
Vue.set
Vue.set(target, key, value)
由于 VUe 无法探测普通的新增 property(比如 this.myObj.newProp = 111),所以通过 Vue.set() 为响应式对象中添加一个 property,可以确保这个 property 是响应式的,并且触发视图更新
- 用于在运行时添加根级别属性,使该属性必须具有响应式能力
- 不能是 Vue 实例,或者 Vue 实例的根数据对象( 即 return {} )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| new Vue({ data() { return { a: 1, str: '', obj: {}, arr: [1, 2, 3, { key: val }] } }, methods: { change() { this.b = 2, this.arr[0] = 111, this.arr[3].key = 'newVal' }, func() { Vue.set(this, c, 3), Vue.set(this.arr, 0, 111) } } })
|
- 不可在运行时直接 set 一个根级别属性( b: 2 ),这样不具有响应式
- 若是初始化时设置 str 为空字符或者 obj 空对象,运行时再 set 是具有响应式的
Vue.use
- Vue.use(plugin) 作用:负责安装插件,其实就是执行插件提供的 install 方法
- 首先会判断插件是否安装过
1 2 3 4 5 6
| const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) { return this }
|
- 未安装过则执行插件提供的 install 方法,具体做什么由插件自己决定
1 2 3 4 5 6 7
| if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) }
|
Vue.mixin
- 负责在全局的配置上合并 options 选项,然后在每个组件生成 vnode 时将全局配置合并到自己的 options 上来
1 2 3 4 5
| Vue.mixin = function (mixin: Object) { this.options = mergeOptions(this.options, mixin) return this }
|
Vue.component | Vue.directive(‘my-directive’, {}) | Vue.filter(‘my-filter’, {})
- 负责注册全局组件
- 其实就是将组件配置注册到全局配置的 components 选项上,然后各个子组件在生成 vnode 时会将全局的 components 选项合并到 局部的 components 配置上
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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 return definition
|
Vue.extend(options)
- Vue.extends 基于 Vue 创建一个子类,参数 options 会作为该子类的默认全局配置,如同 Vue 的默认全局配置一般;
- 所以通过 Vue.extend 扩展一个子类,一大用处就是内置一些公共配置,供子类的子类使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
const Sub = function VueComponent (options) { this._init(options) }
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub Sub.cid = cid++
Sub.options = mergeOptions( Super.options, extendOptions )
Sub.extend = Super.extend Sub.mixin = Super.mixin Sub.use = Super.use
|
Vue.delete(target, key)
- 删除对象的 property,如果对象是响应式的,确保删除能触发视图更新,
- 这个方法主要用于避开 Vue 不能监测到 property 被删除的限制
- 当然不能删除根级别的响应式属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| if (Array.isArray(target) && isValidArrayIndex(key)) { target.splice(key, 1) return } const ob = (target).__ob__ if (!hasOwn(target, key)) { return } delete target[key] if (!ob) { return }
ob.dep.notify()
|
Vue.nextTick(cb)
Vue.nextTick(cb)
方法的作用是延迟回调函数 cb 的执行,一般用于 this.key = newVal
更改数据后,想要立即获取更改后的 DOM 数据1 2 3 4 5 6
| this.key = 'newVal'
Vue.nextTick(function() { })
|
其内部执行过程:
- this.key = ‘newVal’ 触发依赖通知更新,将负责更新的 watcher 放入 watcher 队列
- 将刷新 watcher 的函数放入 callbacks 数组中
- 在浏览器的异步任务队列中放入一个刷新 callbacks 数组的函数
- Vue.nextTick(cb) 插队,将 cb 函数放入 callbacks 数组
- 待将来的某个时刻执行刷新 callbacks 数组的函数
- 然后执行 callbacks 数组的众多函数,触发 watcher.run() 的执行 更新 DOM
- 由于 cb 函数是在后面放到 callbacks 数组,这就保证了先完成的 DOM 更新,再执行 cb 函数