vue2 全局api 分析

本文详细介绍了Vue.js中的关键方法,包括Vue.use用于安装插件的机制,如何防止重复安装并执行插件的install方法;Vue.mixin用于全局混入选项,影响所有后续创建的Vue实例;Vue.set实现响应式地添加或更新对象属性,以及nextTick函数在异步队列中执行回调,确保DOM更新。
摘要由CSDN通过智能技术生成

 1 vue.use()

/**
* Vue.use
* 做了两件事
 * 定义 Vue.use,负责为 Vue 安装插件,做了以下两件事:
 *   1、判断插件是否已经被安装,如果安装则直接结束
 *   2、安装插件,执行插件的 install 方法
 * @param {*} plugin install 方法 或者 包含 install 方法的对象
 * @returns Vue 实例
*/
Vue.use = function(plugin:Function|Object){
// 获取Vue所有插件
 const installPlugins= (this.installedPlugins || this._installedPlugins)
// 判断是否已经安装插件 如果安装过直接返回
if(installPlugins.includes(plugin)) return this
// 如果没安装过
  // 将 Vue 构造函数放到第一个参数位置,然后将这些参数传递给 install 方法
 const args = toArray(installPlugins,1)
args.unshift(this)

   if (typeof plugin.install === 'function') {
    // plugin 是一个对象,则执行其 install 方法安装插件
    plugin.install.apply(plugin, args)
  } else if (typeof plugin === 'function') {
    // 执行直接 plugin 方法安装插件
    plugin.apply(null, args)
  }
  // 在 插件列表中 添加新安装的插件
  installedPlugins.push(plugin)
  return this

}
  1. Vue.mixin
    /**
     * 定义 Vue.mixin,负责全局混入选项,影响之后所有创建的 Vue 实例,这些实例会合并全局混入的选项
     * @param {*} mixin Vue 配置对象
     * @returns 返回 Vue 实例
     * mergeOptions 合并两个选项,出现相同配置项时,子选项会覆盖父选项的配置
     */
    Vue.mixin = function (mixin: Object) {
      // 在 Vue 的默认配置项上合并 mixin 对象
      this.options = mergeOptions(this.options, mixin)
      return this
    }
    

4 Vue.set = set

/**
 * 通过 Vue.set 或者 this.$set 方法给 target 的指定 key 设置值 val
 * 如果 target 是对象,并且 key 原本不存在,则为新 key 设置响应式,然后执行依赖通知
 */
export default set =function (target:Array|Object,key:any,val:any){
    // 判断 taget 是否为空
    if(!target){
        console.warn('请输入target')
    }
    // 判断target 是否为数组 如果是数组根据下标通过splice 实现响应式
    // 更新数组指定下标的元素,Vue.set(array, idx, val),通过 splice 方法实现响应式更新
    // isValidArrayIndex(key)) 判断转换成数字
    if(Array.isArray(target)&& isValidArrayIndex(key)){
        // 获取最大值
        target.length = Math.max(target.length,key)
        target.slice(key,1,val)
return val
    }
    // 判断是否为对象 对象如果已有该属性直接更新
    if(key in target && !(key in Object.prototype)){
        target[key] = val
        return val
    }
const ob = (target:any)._ob_
  // 不能向 Vue 实例或者 $data 添加动态添加响应式属性,vmCount 的用处之一,
  // this.$data 的 ob.vmCount = 1,表示根组件,其它子组件的 vm.vmCount 都是 0
 
  // target 不是响应式对象,新属性会被设置,但是不会做响应式处理
  if (!ob) {
    target[key] = val
    return val
  }
 // 给对象定义新属性,通过 defineReactive 方法设置响应式,并触发依赖更新
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val

}

nextTick

const callbacks = []
/**
 * 完成两件事:
 *   1、用 try catch 包装 flushSchedulerQueue 函数,然后将其放入 callbacks 数组
 *   2、如果 pending 为 false,表示现在浏览器的任务队列中没有 flushCallbacks 函数
 *     如果 pending 为 true,则表示浏览器的任务队列中已经被放入了 flushCallbacks 函数,
 *     待执行 flushCallbacks 函数时,pending 会被再次置为 false,表示下一个 flushCallbacks 函数可以进入
 *     浏览器的任务队列了
 * pending 的作用:保证在同一时刻,浏览器的任务队列中只有一个 flushCallbacks 函数
 * @param {*} cb 接收一个回调函数 => flushSchedulerQueue
 * @param {*} ctx 上下文
 * @returns 
 */
export function nextTick (cb?: Function, ctx?: Object) {

let _resolve
 // 用 callbacks 数组存储经过包装的 cb 函数
callbacks.push(()=>{
    if(cb){
        // 用try catch 包装回调函数 便于捕获错误
        try{
            cb.call(ctx)
        } catch(e){
            handleError(e,ctx,'nextTick')
        }
    } else if(_resolve){
        _resolve(ctx)
    }

})

    if(!pending){
        pending = true
     // 执行 timerFunc,在浏览器的任务队列中(首选微任务队列)放入 flushCallbacks 函数
    timerFunc()
    }

 // $flow-disable-line
  if (!cb && typeof Promise !== 'undefined') {
    return new Promise(resolve => {
      _resolve = resolve
    })
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值