feat: v-model targe value support variable (#331)

This commit is contained in:
Amour1688 2021-03-03 10:23:32 +08:00
parent ec50fddc8a
commit 98b4f92f48
2 changed files with 36 additions and 15 deletions

View File

@ -81,14 +81,19 @@ const dedupeProperties = (properties: t.ObjectProperty[] = [], mergeProps?: bool
const knownProps = new Map<string, t.ObjectProperty>(); const knownProps = new Map<string, t.ObjectProperty>();
const deduped: t.ObjectProperty[] = []; const deduped: t.ObjectProperty[] = [];
properties.forEach((prop) => { properties.forEach((prop) => {
const { value: name } = prop.key as t.StringLiteral; if (t.isStringLiteral(prop.key)) {
const existing = knownProps.get(name); const { value: name } = prop.key;
if (existing) { const existing = knownProps.get(name);
if (name === 'style' || name === 'class' || name.startsWith('on')) { if (existing) {
mergeAsArray(existing, prop); if (name === 'style' || name === 'class' || name.startsWith('on')) {
mergeAsArray(existing, prop);
}
} else {
knownProps.set(name, prop);
deduped.push(prop);
} }
} else { } else {
knownProps.set(name, prop); // v-model target with variable
deduped.push(prop); deduped.push(prop);
} }
}); });
@ -235,42 +240,58 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
if (['models', 'model'].includes(directiveName)) { if (['models', 'model'].includes(directiveName)) {
values.forEach((value, index) => { values.forEach((value, index) => {
const argVal = (args[index] as t.StringLiteral)?.value; const propName = args[index];
const propName = argVal || 'modelValue'; // v-model target with variable
const isIdentifierProp = t.isIdentifier(propName);
// must be v-model or v-models and is a component // must be v-model or v-models and is a component
if (!directive) { if (!directive) {
properties.push( properties.push(
t.objectProperty(t.stringLiteral(propName), value as any), t.objectProperty(t.isNullLiteral(propName)
? t.stringLiteral('modelValue') : propName, value as any, isIdentifierProp),
); );
dynamicPropNames.add(propName); if (!isIdentifierProp) {
dynamicPropNames.add((propName as t.StringLiteral)?.value || 'modelValue');
}
if (modifiers[index]?.size) { if (modifiers[index]?.size) {
properties.push( properties.push(
t.objectProperty( t.objectProperty(
t.stringLiteral(`${argVal || 'model'}Modifiers`), isIdentifierProp
? t.binaryExpression('+', propName, t.stringLiteral('Modifiers'))
: t.stringLiteral(`${(propName as t.StringLiteral)?.value || 'model'}Modifiers`),
t.objectExpression( t.objectExpression(
[...modifiers[index]].map((modifier) => t.objectProperty( [...modifiers[index]].map((modifier) => t.objectProperty(
t.stringLiteral(modifier), t.stringLiteral(modifier),
t.booleanLiteral(true), t.booleanLiteral(true),
)), )),
), ),
isIdentifierProp,
), ),
); );
} }
} }
const updateName = isIdentifierProp
? t.binaryExpression('+', t.stringLiteral('onUpdate'), propName)
: t.stringLiteral(`onUpdate:${(propName as t.StringLiteral)?.value || 'modelValue'}`);
properties.push( properties.push(
t.objectProperty( t.objectProperty(
t.stringLiteral(`onUpdate:${propName}`), updateName,
t.arrowFunctionExpression( t.arrowFunctionExpression(
[t.identifier('$event')], [t.identifier('$event')],
t.assignmentExpression('=', value as any, t.identifier('$event')), t.assignmentExpression('=', value as any, t.identifier('$event')),
), ),
isIdentifierProp,
), ),
); );
dynamicPropNames.add(`onUpdate:${propName}`); if (!isIdentifierProp) {
dynamicPropNames.add((updateName as t.StringLiteral).value);
} else {
hasDynamicKeys = true;
}
}); });
} }
} else { } else {

View File

@ -42,7 +42,7 @@ const parseDirectives = (params: {
const { const {
name, path, value, state, tag, isComponent, name, path, value, state, tag, isComponent,
} = params; } = params;
const args: Array<t.StringLiteral| t.NullLiteral> = []; const args: Array<t.StringLiteral | t.Identifier | t.NullLiteral> = [];
const vals: t.Expression[] = []; const vals: t.Expression[] = [];
const modifiersSet: Set<string>[] = []; const modifiersSet: Set<string>[] = [];
const underscoreModifiers = name.split('_'); const underscoreModifiers = name.split('_');
@ -77,7 +77,7 @@ const parseDirectives = (params: {
const [first, second, third] = elements; const [first, second, third] = elements;
let modifiers = underscoreModifiers; let modifiers = underscoreModifiers;
if (t.isStringLiteral(second)) { if (t.isStringLiteral(second) || t.isIdentifier(second)) {
args.push(second); args.push(second);
modifiers = parseModifiers(third as t.ArrayExpression); modifiers = parseModifiers(third as t.ArrayExpression);
} else if (t.isArrayExpression(second)) { } else if (t.isArrayExpression(second)) {