baseModule

ref

export default {
  // Vnode is created and ref is registered
  create(_,vnode){
    registerRef(vnode)
  },
  // vnode update,ref update
  update(oldVnode,vnode){
    if(oldVnode.data.ref ! == vnode.data.ref){ registerRef(oldVnode,true)
      registerRef(vnode)
    }
  },
  // VNode destroy, destroy ref
  destroy(vnode){
    registerRef(vnode,true)}}function registerRef(vnode,isRemoval){
  // Get the ref on vnode
  const key = vnode.data.ref
  if(! isDef(key))return
  // Get the VM instance
  const vm = vnode.context
  // Get the mounted node
  const ref = vnode.componentInstance || vnode.elm
  // All refs on the current VM instance
  const refs = vm.$refs
  / / delete the ref
  if(isRemoval){
    if(Array.isArray(refs[key])){
      remove(refs[key],ref)
    }else if(refs[key] === ref){
      refs[key] = undefined}}else{
    // Determine whether to add in a loop
    if(vnode.data.refInFor){
      if(!Array.isArray(refs[key])){
        refs[key] = ref
      }else if(refs[key].indexOf(ref) < 0){
        refs[key].push(ref)
      }
    }else{
      // Add ref to refs
      refs[key] = ref
    }
  }
}
Copy the code

directives

export default{
  create:updateDirectives,
  update:updateDirectives,
  destroy:function unbindDirectives(vnode){
    updateDirectives(vnode,emptyNode)
  }
}
function updateDirectives(oldVnode,vnode){
  // Update the node according to the instructions on the node
  if(oldVnode.data.directives || vnode.data.directives){
    _update(oldVnode,vnode)
  }
}

function _update(oldVnode,vnode){
  // Determine whether a node is created or deleted
  const isCreate = oldVnode === emptyNode
  const isDestroy = vnode === emptyNode
  // Get the node instruction
  const oldDirs = normalizeDirectives(oldVnode.data.directives,oldVnode.context)
  const newDirs = normalizeDirectives(vnode.data.directives,vnode.context)
  const dirsWithInsert = []
  const dirsWithPostpatch = []
  let key,oldDir,dir
  for(key in newDirs){
    oldDir = oldDirs[key]
    dir = newDirs[key]
    / / new instructions
    if(! oldDir){// Bind a new directive
      callHook(dir,'bind',vnode,oldVnode)
      // Insert a new directive
      if(dir.def && dir.def.inserted){
        dirsWithInsert.push(dir)
      }
    }else{
      // Update instructions
      dir.oldValue = oldDir.value
      dir.oldArg = oldDir.arg
      callHook(dir,'update',vnode,oldVnode)
      if(dir.def && dir.def.componentUpdated){
        dirsWithPostpatch.push(dir)
      }
    }
  }
  if(dirsWithInsert.length){
    const callInsert = () = > {
      for(let i = 0; i < dirsWithInsert.length; i++){ callHook(dirsWithInsert[i],'inserted',vnode,oldVnode)
      }
    }
    // If a new VNode is added, execute the insert + post-insert hook function
    if(isCreate){
      mergeVnodeHook(vnode,'insert',callInsert)
    }else{
      callInsert()
    }
  }
  // Executes componentUpdated hook
  if(dirsWithPostpatch.length){
    mergeVnodeHook(vnode,'postpatch'.() = > {
      for(let i = 0; i < dirsWithPostpatch.length; i ++){
        callHook(dirsWithPostpatch[i],'componentUpdated',vnode,oldVnode)
      }
    })
  }
  if(! isCreate){// Execute the remove operation
    for(key in oldDirs){
      if(! newDirs[key]){ callHook(oldDirs[key],'unbind',oldVnode,oldVnode,isDestroy)
      }
    }
  }
}
Copy the code