Skip to content

Commit 98b4f92

Browse files
committed
feat: v-model targe value support variable (#331)
1 parent ec50fdd commit 98b4f92

2 files changed

Lines changed: 36 additions & 15 deletions

File tree

packages/babel-plugin-jsx/src/buildProps.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,19 @@ const dedupeProperties = (properties: t.ObjectProperty[] = [], mergeProps?: bool
8181
const knownProps = new Map<string, t.ObjectProperty>();
8282
const deduped: t.ObjectProperty[] = [];
8383
properties.forEach((prop) => {
84-
const { value: name } = prop.key as t.StringLiteral;
85-
const existing = knownProps.get(name);
86-
if (existing) {
87-
if (name === 'style' || name === 'class' || name.startsWith('on')) {
88-
mergeAsArray(existing, prop);
84+
if (t.isStringLiteral(prop.key)) {
85+
const { value: name } = prop.key;
86+
const existing = knownProps.get(name);
87+
if (existing) {
88+
if (name === 'style' || name === 'class' || name.startsWith('on')) {
89+
mergeAsArray(existing, prop);
90+
}
91+
} else {
92+
knownProps.set(name, prop);
93+
deduped.push(prop);
8994
}
9095
} else {
91-
knownProps.set(name, prop);
96+
// v-model target with variable
9297
deduped.push(prop);
9398
}
9499
});
@@ -235,42 +240,58 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
235240

236241
if (['models', 'model'].includes(directiveName)) {
237242
values.forEach((value, index) => {
238-
const argVal = (args[index] as t.StringLiteral)?.value;
239-
const propName = argVal || 'modelValue';
243+
const propName = args[index];
244+
// v-model target with variable
245+
const isIdentifierProp = t.isIdentifier(propName);
240246

241247
// must be v-model or v-models and is a component
242248
if (!directive) {
243249
properties.push(
244-
t.objectProperty(t.stringLiteral(propName), value as any),
250+
t.objectProperty(t.isNullLiteral(propName)
251+
? t.stringLiteral('modelValue') : propName, value as any, isIdentifierProp),
245252
);
246-
dynamicPropNames.add(propName);
253+
if (!isIdentifierProp) {
254+
dynamicPropNames.add((propName as t.StringLiteral)?.value || 'modelValue');
255+
}
247256

248257
if (modifiers[index]?.size) {
249258
properties.push(
250259
t.objectProperty(
251-
t.stringLiteral(`${argVal || 'model'}Modifiers`),
260+
isIdentifierProp
261+
? t.binaryExpression('+', propName, t.stringLiteral('Modifiers'))
262+
: t.stringLiteral(`${(propName as t.StringLiteral)?.value || 'model'}Modifiers`),
252263
t.objectExpression(
253264
[...modifiers[index]].map((modifier) => t.objectProperty(
254265
t.stringLiteral(modifier),
255266
t.booleanLiteral(true),
256267
)),
257268
),
269+
isIdentifierProp,
258270
),
259271
);
260272
}
261273
}
262274

275+
const updateName = isIdentifierProp
276+
? t.binaryExpression('+', t.stringLiteral('onUpdate'), propName)
277+
: t.stringLiteral(`onUpdate:${(propName as t.StringLiteral)?.value || 'modelValue'}`);
278+
263279
properties.push(
264280
t.objectProperty(
265-
t.stringLiteral(`onUpdate:${propName}`),
281+
updateName,
266282
t.arrowFunctionExpression(
267283
[t.identifier('$event')],
268284
t.assignmentExpression('=', value as any, t.identifier('$event')),
269285
),
286+
isIdentifierProp,
270287
),
271288
);
272289

273-
dynamicPropNames.add(`onUpdate:${propName}`);
290+
if (!isIdentifierProp) {
291+
dynamicPropNames.add((updateName as t.StringLiteral).value);
292+
} else {
293+
hasDynamicKeys = true;
294+
}
274295
});
275296
}
276297
} else {

packages/babel-plugin-jsx/src/parseDirectives.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const parseDirectives = (params: {
4242
const {
4343
name, path, value, state, tag, isComponent,
4444
} = params;
45-
const args: Array<t.StringLiteral| t.NullLiteral> = [];
45+
const args: Array<t.StringLiteral | t.Identifier | t.NullLiteral> = [];
4646
const vals: t.Expression[] = [];
4747
const modifiersSet: Set<string>[] = [];
4848
const underscoreModifiers = name.split('_');
@@ -77,7 +77,7 @@ const parseDirectives = (params: {
7777
const [first, second, third] = elements;
7878
let modifiers = underscoreModifiers;
7979

80-
if (t.isStringLiteral(second)) {
80+
if (t.isStringLiteral(second) || t.isIdentifier(second)) {
8181
args.push(second);
8282
modifiers = parseModifiers(third as t.ArrayExpression);
8383
} else if (t.isArrayExpression(second)) {

0 commit comments

Comments
 (0)