merge-hook
export function mergeVNodeHook(def,hookKey,hook){
// Get the hook function
if(def instanceof VNode){
def = def.data.hook || def.data.hook = {}
}
let invoker
const oldHook = def[hookKey]
// Execute the hook function to remove wrappedHook
function wrappedHook(){
hook.apply(this.arguments)
remove(invoker.fns,wrappedHook)
}
// Add a hook function to vNode
if(isUndef(oldHook)){
// Execute the existing hook function and delete it
invoker = createFnInvoker([wrappedHook])
}else{
// Merge the current hook function into FNS if merged exists
if(isDef(oldHook.fns) && isTrue(oldHook.merged)){
invoker = oldHook
invoker.fns.push(wrappedHook)
}else{
// Otherwise create FNS
invoker = createFnInvoker([oldHook,warppedHook])
}
}
invoker.merged = true
def[hookKey] = invoker
}
Copy the code
extractPropsFormVNodeData
export function extractPropsFormVNodeData(data,Ctor,tag){
// Get the Props of the VM
const propsOptions = Ctor.options.props
if(isUndef(propsOptions)){
return
}
const res = {}
const { attrs, props } = data
if(isDef(attrs) || isDef(props)){
for(const key in propsOptions){
// Hump conversion
const altKey = hyphenate(key)
...// prop precautions
// Add props or attrs to res, and remove the key or altKey that exists in attrs
checkProp(res,props,key,altKey,true) || checkProp(res,attrs,key,altKey,false)}}return res
}
Copy the code
updateListeners
export function updateListeners(on,oldOn,add,remove,createOnceHandler,vm){
let name,def,cur,old,event
for(name in on){
def = cur = on[name]
old = oldOn[name]
// Gets the attributes of the current event
event = normalizeEvent(name)
if(isUndef(cur)){
// The current event does not existprocess.env.NODE_ENV ! = ='production' && warn(`Invalid handler for event "${event.name}":got ` + String(cur))
}else if(isUndef(old)){
// The previous event did not exist
if(isUndef(cur.fns)){
cur = on[name] = createFnInvoker(cur,vm)
}
if(isTrue(event.once)){
cur = on[name] = createOnceHandler(event.name,cur,event.capture)
}
// Add the event again according to event.name
add(event.name,cur,event.capture,event.passive,event.params)
}else if(cur ! == old){ old.fns = cur on[name] = old } }for(name in oldOn){
if(isUndef(on[name])){
// If the new event does not exist, remove the event
event = normalizeEvent(name)
remove(event.name,oldOn[name],event.capture)
}
}
}
Copy the code
normalizeChildren
// Generate vnodelist based on type
export function normalizeChildren(children){
return isPrimitive(children) ? [createTextVNode(children)] : Array.isArray(children) ? normalizeArrayChildren(children) : undefined
}
// The text node is converted to one, and the non-text node is stored normally
function normalizeArrayChildren(children,nestedIndex){
const res = []
let i,c,lastIndex,last
for(i = 0; i < children.length; i++){
c = children[i]
if(isUndef(c) || typeof c === 'boolean') continue
lastIndex = res.length - 1
last = res[lastIndex]
if(Array.isArray(c)){
// The sequential subnode is stored in the res
if(c.length > 0){
c = normalizeArrayChildren(c,`${nestedIndex || ' '}_${i}`)
// C is a textNode and the last node is a textNode
if(isTextNode(c[0]) && isTextNode(last)){
res[lastIndex] = createTextVNode(last.text + c[0].text)
c.shift()
}
res.push.apply(res,c)
}
}else if(isPrimitive(c)){
// Store textNode into res
if(isTextNode(last)){
res[lastIndex] = createTextVNode(last.text + c)
}else if(c ! = =' '){
res.push(createTextVNode(c))
}
}else{
if(isTextNode(c) && isTextNode(last)){
res[lastIndex] = createTextVNode(last.text + c.text)
}else{
if(isTrue(children._isVList) && isDef(c.tag) && isUndef(c.key) && isDef(nestedIndex)){
c.key = `_vlist${nestedIndex}_${i}__ `
}
res.push(c)
}
}
}
return res
}
Copy the code
resolveAsyncComponent
export function resolveAsyncComponent(factory,baseCtor){
/ / the correct factory
if(isTrue(factory.error) && isDef(factory.errorComp)){
return factory.errorComp
}
// Get the VM instance
if(isDef(factory.resolved)){
return factory.resolved
}
// Get the vm instance for the current operation
const owner = currentRenderingInstance
/ / in the market metrix
if(owner && isDef(factory.owners) && factory.owners.indefOf(owner) === -1){
factory.owners.push(owner)
}
/ / loading condition
if(isTrue(factory.loading) && isDef(factory.loadingComp)){
return factory.loadingComp
}
if(owner && ! isDef(factory.owners)){const owners = factory.owners = [owner]
let sync = true
let timerLoading = null
let timerTimeout = null
// Vm mount event, remove owner when destroyed
owner.$on('hook:destroyed'.() = > remove(owners,owner))
// Force render vm
const forceRender = (renderCompleted) = > {
for(let i = 0; i < owners.length; i ++){
owners[i].$forceUpdate()
}
// If rendering is complete, empty the VM
if(renderCompleted){
owners.length = 0
if(timerLoading ! = =null) {clearTimeout(timerLoading)
timerLoading = null
}
if(timerTimeout ! = =null) {clearTimeout(timerTimeout)
timerTimeout = null}}}const resolve = once((res) = > {
factory.resolved = ensureCtor(res,baseCtor)
if(! sync){ forceRender(true)}else{
owners.length = 0}})const reject = once((reason) = >{ process.env.NODE_ENV ! = ='production' && warn(`Failed to resolve async component: The ${String(factory)}` + (reason ? `\nReason:${reason}` : ' '))
if(isDef(factory.errorComp)){
factory.error = true
forceRender(true)}})// Determine whether res is asynchronous
const res = factory(resolve,reject)
if(isObject(res)){
// If it's a Promise
if(isPromise(res)){
if(isUndef(factory.resolved)){
res.then(resolve,reject)
}
}else if(isPromise(res.component)){
res.component.then(resolve,reject)
if(isDef(factory.error)){
factory.errorComp = ensureCtor(res.error,baseCtor)
}
// Parse whether the asynchrony is complete
if(isDef(res.loading)){
factory.loadingComp = ensureCtor(res.loading,baseCtor)
// Determine whether to delay rendering
if(res.delay === 0){
factory.loading = true
}else{
timerLoading = setTimeout(() = > {
timerLoading = null
// The dom is still in loading state
if(isUndef(factory.resolved) && isUndef(factory.error)){
factory.loading = true
forceRender(false)
}
},res.delay || 200)}}// Determine parsing timeout,reject
if(isDef(res.timeout)){
timerTimeout = setTimeout(() = > {
timerTimeout = null
if(isUndef(factory.resolved)){ reject(process.env.NODE_ENV ! = ='production' ? `timeout (${res.timeout}ms)`:null)
}
},res.timeout)
}
}
}
sync = false
// Determine if component parsing is complete
return factory.loading ? factory.loadingComp : factory.resolved
}
}
Copy the code
getFirstComponentChild
// Get the first child of Component
export function getFirstComponentChild(children){
if(Array.isArray(children)){
for(let i = 0; i < children.length; i ++){
const c = children[i]
if(isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))){
return c
}
}
}
}
Copy the code
isAsyncPlaceholder
export function isAsyncPlaceholder(node){
return node.isComment && node.asyncFactory
}
Copy the code
normalizeScopedSlots
export function normalizeScopedSlots(slots,normalSlots,prevSlots){
let res
const hasNormalSlots = Object.keys(normalSlots).length > 0
constisStable = slots ? !!!!! slots.$stable : ! hasNoramlSlotsconst key = slots && slots.$key
/ / get slots
if(! slots){ res = {} }else if(slots._normalized){
return slots._normalized
}else if(isStable && prevSlots && prevSlots ! == emptyObject && key === prevSlots.$key && ! hasNormalSlots && ! prevSlots.$hasNormal){return prevSlots
}else {
res = {}
for(const key in slots){
if(slots[key] && key[0]! = ='$'){
res[key] = normalizeScopeSlot(normalSlots,key,slots[key])
}
}
}
// Extend slots according to normalSlots
for(const key in normalSlots){
if(! keyin res){
res[key] = proxyNormalSlot(normalSlots,key)
}
}
if(slots && Object.isExtensible(slots)){
slots._normalized = res
}
def(res,'$stable',isStable)
def(res,'$key',key)
def(res,'$hasNormal',hasNormalSlots)
return res
}
Copy the code