wip: generate valid v-model and TS code in script setup inline mode
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 ? `}` : `)`
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user