refactor(compiler-vapor): extract v-on

This commit is contained in:
三咲智子 Kevin Deng 2023-12-07 00:39:31 +08:00
parent 3d9f0ac614
commit 082b6c40b5
No known key found for this signature in database
GPG Key ID: 69992F2250DFD93E
3 changed files with 49 additions and 43 deletions

View File

@ -18,6 +18,7 @@ import { transformOnce } from './transforms/vOnce'
import { transformElement } from './transforms/transformElement' import { transformElement } from './transforms/transformElement'
import { transformVHtml } from './transforms/vHtml' import { transformVHtml } from './transforms/vHtml'
import { transformVText } from './transforms/vText' import { transformVText } from './transforms/vText'
import { transformVBind } from './transforms/vBind'
import { transformVOn } from './transforms/vOn' import { transformVOn } from './transforms/vOn'
import { transformInterpolation } from './transforms/transformInterpolation' import { transformInterpolation } from './transforms/transformInterpolation'
import type { HackOptions } from './ir' import type { HackOptions } from './ir'
@ -92,6 +93,7 @@ export function getBaseTransformPreset(
return [ return [
[transformOnce, transformInterpolation, transformElement], [transformOnce, transformInterpolation, transformElement],
{ {
bind: transformVBind,
on: transformVOn, on: transformVOn,
html: transformVHtml, html: transformVHtml,
text: transformVText, text: transformVText,

View File

@ -2,12 +2,9 @@ import {
type ElementNode, type ElementNode,
type AttributeNode, type AttributeNode,
NodeTypes, NodeTypes,
ErrorCodes,
createCompilerError,
ElementTypes, ElementTypes,
createSimpleExpression,
} from '@vue/compiler-dom' } from '@vue/compiler-dom'
import { camelize, isBuiltInDirective, isVoidTag } from '@vue/shared' import { isBuiltInDirective, isVoidTag } from '@vue/shared'
import { NodeTransform, TransformContext } from '../transform' import { NodeTransform, TransformContext } from '../transform'
import { VaporDirectiveNode, IRNodeTypes } from '../ir' import { VaporDirectiveNode, IRNodeTypes } from '../ir'
@ -69,54 +66,17 @@ function transformProp(
return return
} }
let { arg, exp, loc } = prop
const directiveTransform = context.options.directiveTransforms[name] const directiveTransform = context.options.directiveTransforms[name]
if (directiveTransform) { if (directiveTransform) {
directiveTransform(prop, node, context) directiveTransform(prop, node, context)
} else if (!isBuiltInDirective(name)) { } else if (!isBuiltInDirective(name)) {
// custom directive
context.registerOperation({ context.registerOperation({
type: IRNodeTypes.WITH_DIRECTIVE, type: IRNodeTypes.WITH_DIRECTIVE,
element: context.reference(), element: context.reference(),
name, name,
binding: exp, binding: prop.exp,
loc: prop.loc, loc: prop.loc,
}) })
} }
switch (name) {
case 'bind': {
if (!arg) {
// TODO support v-bind="{}"
return
}
if (!exp) {
// shorthand syntax https://github.com/vuejs/core/pull/9451
const propName = camelize(arg.content)
exp = createSimpleExpression(propName, false, arg.loc)
exp.ast = null
}
if (!exp.content.trim()) {
context.options.onError(
createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
)
context.template += ` ${arg.content}=""`
return
}
context.registerEffect(
[exp],
[
{
type: IRNodeTypes.SET_PROP,
loc: prop.loc,
element: context.reference(),
name: arg,
value: exp,
},
],
)
break
}
}
} }

View File

@ -0,0 +1,44 @@
import {
createCompilerError,
createSimpleExpression,
ErrorCodes,
} from '@vue/compiler-core'
import { camelize } from '@vue/shared'
import { IRNodeTypes } from '../ir'
import type { DirectiveTransform } from '../transform'
export const transformVBind: DirectiveTransform = (dir, node, context) => {
let { arg, exp, loc } = dir
if (!arg) {
// TODO support v-bind="{}"
return
}
if (!exp) {
// shorthand syntax https://github.com/vuejs/core/pull/9451
const propName = camelize(arg.content)
exp = createSimpleExpression(propName, false, arg.loc)
exp.ast = null
}
if (!exp.content.trim()) {
context.options.onError(
createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
)
context.template += ` ${arg.content}=""`
return
}
context.registerEffect(
[exp],
[
{
type: IRNodeTypes.SET_PROP,
loc: dir.loc,
element: context.reference(),
name: arg,
value: exp,
},
],
)
}