wip: generate valid v-model and TS code in script setup inline mode

This commit is contained in:
Evan You
2020-11-17 12:42:58 -05:00
parent 6e870f5b30
commit c15bd6235e
6 changed files with 52 additions and 11 deletions

View File

@@ -14,6 +14,7 @@ import {
hasScopeRef,
isStaticExp
} from '../utils'
import { helperNameMap, IS_REF, UNREF } from '../runtimeHelpers'
export const transformModel: DirectiveTransform = (dir, node, context) => {
const { exp, arg } = dir
@@ -24,10 +25,16 @@ export const transformModel: DirectiveTransform = (dir, node, context) => {
return createTransformProps()
}
const rawExp = exp.loc.source
const expString =
exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : exp.loc.source
exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : rawExp
if (!isMemberExpression(expString)) {
// im SFC <script setup> inline mode, the exp may have been transformed into
// _unref(exp)
const isUnrefExp =
!__BROWSER__ && expString.startsWith(`_${helperNameMap[UNREF]}`)
if (!isMemberExpression(expString) && !isUnrefExp) {
context.onError(
createCompilerError(ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION, exp.loc)
)
@@ -53,14 +60,25 @@ export const transformModel: DirectiveTransform = (dir, node, context) => {
: createCompoundExpression(['"onUpdate:" + ', arg])
: `onUpdate:modelValue`
const assigmentExp = isUnrefExp
? // v-model used on a potentially ref binding in <script setup> inline mode.
// not the most beautiful codegen here but it gets the job done.
createSimpleExpression(
`$event => { if (${context.helperString(IS_REF)}(${rawExp})) {` +
`${rawExp}.value = $event` +
` } else {${context.isTS ? `\n//@ts-ignore\n` : ``}` +
`${rawExp} = $event` +
` }}`,
false,
exp.loc
)
: createCompoundExpression([`$event => (`, exp, ` = $event)`])
const props = [
// modelValue: foo
createObjectProperty(propName, dir.exp!),
// "onUpdate:modelValue": $event => (foo = $event)
createObjectProperty(
eventName,
createCompoundExpression([`$event => (`, exp, ` = $event)`])
)
createObjectProperty(eventName, assigmentExp)
]
// cache v-model handler if applicable (when it doesn't refer any scope vars)

View File

@@ -122,9 +122,13 @@ export const transformOn: DirectiveTransform = (
if (isInlineStatement || (shouldCache && isMemberExp)) {
// wrap inline statement in a function expression
exp = createCompoundExpression([
`${isInlineStatement ? `$event` : `(...args)`} => ${
hasMultipleStatements ? `{` : `(`
}`,
`${
isInlineStatement
? `$event`
: `${
!__BROWSER__ && context.isTS ? `\n//@ts-ignore\n` : ``
}(...args)`
} => ${hasMultipleStatements ? `{` : `(`}`,
exp,
hasMultipleStatements ? `}` : `)`
])