if(isProp.type===NodeTypes.ATTRIBUTE&&isProp.value!.content.startsWith('vue:')){// <button is="vue:xxx">
// if not <component>, only is value that starts with "vue:" will be
// treated as component by the parse phase and reach here, unless it's
// compat mode where all is values are considered components
tag=isProp.value!.content.slice(4)}
if(builtIn){// built-ins are simply fallthroughs / have special handling during ssr
// so we don't need to import their runtime equivalents
if(!ssr)context.helper(builtIn)returnbuiltIn}
if(!__BROWSER__&&context.selfName&&capitalize(camelize(tag))===context.selfName){context.helper(RESOLVE_COMPONENT)// codegen.ts has special check for __self postfix when generating
// component imports, which will pass additional `maybeSelfReference` flag
// to `resolveComponent`.
context.components.add(tag+`__self`)returntoValidAssetId(tag,`component`)}
if(// #938: elements with dynamic keys should be forced into blocks
(isVBind&&isStaticArgOf(arg,'key'))||// inline before-update hooks need to force block so that it is invoked
// before children
(isVOn&&hasChildren&&isStaticArgOf(arg,'vue:before-update'))){shouldUseBlock=true}
如果有动态绑定的参数, 这里会推入到mergeArgs中去
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
hasDynamicKeys=trueif(exp){if(isVBind){// have to merge early for compat build check
pushMergeArg()mergeArgs.push(exp)}else{// v-on="obj" -> toHandlers(obj)
pushMergeArg({type:NodeTypes.JS_CALL_EXPRESSION,loc,callee: context.helper(TO_HANDLERS),arguments: isComponent?[exp]:[exp,`true`]})}}
constdirectiveTransform=context.directiveTransforms[name]if(directiveTransform){// has built-in directive transform.
const{props,needRuntime}=directiveTransform(prop,node,context)!ssr&&props.forEach(analyzePatchFlag)if(isVOn&&arg&&!isStaticExp(arg)){pushMergeArg(createObjectExpression(props,elementLoc))}else{properties.push(...props)}if(needRuntime){runtimeDirectives.push(prop)if(isSymbol(needRuntime)){directiveImportMap.set(prop,needRuntime)}}}elseif(!isBuiltInDirective(name)){// no built-in transform, this is a user custom directive.
runtimeDirectives.push(prop)// custom dirs may use beforeUpdate so they need to force blocks
// to ensure before-update gets called before children update
if(hasChildren){shouldUseBlock=true}}
// has v-bind="object" or v-on="object", wrap with mergeProps
if(mergeArgs.length){// close up any not-yet-merged props
pushMergeArg()if(mergeArgs.length>1){propsExpression=createCallExpression(context.helper(MERGE_PROPS),mergeArgs,elementLoc)}else{// single v-bind with nothing else - no need for a mergeProps call
propsExpression=mergeArgs[0]}}elseif(properties.length){propsExpression=createObjectExpression(dedupeProperties(properties),elementLoc)}
switch(propsExpression.type){caseNodeTypes.JS_OBJECT_EXPRESSION:// means that there is no v-bind,
// but still need to deal with dynamic key binding
letclassKeyIndex=-1letstyleKeyIndex=-1lethasDynamicKey=falsefor(leti=0;i<propsExpression.properties.length;i++){constkey=propsExpression.properties[i].keyif(isStaticExp(key)){if(key.content==='class'){classKeyIndex=i}elseif(key.content==='style'){styleKeyIndex=i}}elseif(!key.isHandlerKey){hasDynamicKey=true}}constclassProp=propsExpression.properties[classKeyIndex]conststyleProp=propsExpression.properties[styleKeyIndex]// no dynamic key
if(!hasDynamicKey){if(classProp&&!isStaticExp(classProp.value)){classProp.value=createCallExpression(context.helper(NORMALIZE_CLASS),[classProp.value])}if(styleProp&&// the static style is compiled into an object,
// so use `hasStyleBinding` to ensure that it is a dynamic style binding
(hasStyleBinding||(styleProp.value.type===NodeTypes.SIMPLE_EXPRESSION&&styleProp.value.content.trim()[0]===`[`)||// v-bind:style and style both exist,
// v-bind:style with static literal object
styleProp.value.type===NodeTypes.JS_ARRAY_EXPRESSION)){styleProp.value=createCallExpression(context.helper(NORMALIZE_STYLE),[styleProp.value])}}else{// dynamic key binding, wrap with `normalizeProps`
propsExpression=createCallExpression(context.helper(NORMALIZE_PROPS),[propsExpression])}breakcaseNodeTypes.JS_CALL_EXPRESSION:// mergeProps call, do nothing
breakdefault:// single v-bind
propsExpression=createCallExpression(context.helper(NORMALIZE_PROPS),[createCallExpression(context.helper(GUARD_REACTIVE_PROPS),[propsExpression])])break}