mirror of
https://github.com/vuejs/babel-plugin-jsx.git
synced 2024-11-10 09:39:14 +08:00
fix: wrong compilation result of withDirectives (#404)
This commit is contained in:
parent
cbad0e5c5f
commit
224196d3ec
@ -242,8 +242,7 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
|
||||
values.forEach((value, index) => {
|
||||
const propName = args[index];
|
||||
// v-model target with variable
|
||||
// const isIdentifierProp = t.isIdentifier(propName);
|
||||
const isDynamic = !t.isStringLiteral(propName) && !t.isNullLiteral(propName);
|
||||
const isDynamic = propName && !t.isStringLiteral(propName) && !t.isNullLiteral(propName);
|
||||
|
||||
// must be v-model or v-models and is a component
|
||||
if (!directive) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as t from '@babel/types';
|
||||
import { NodePath } from '@babel/traverse';
|
||||
import { createIdentifier } from './utils';
|
||||
import { State, ExcludesBoolean } from '.';
|
||||
import { State } from '.';
|
||||
|
||||
export type Tag = t.Identifier | t.MemberExpression | t.StringLiteral | t.CallExpression;
|
||||
|
||||
@ -24,7 +24,7 @@ const getType = (path: NodePath<t.JSXOpeningElement>) => {
|
||||
return typePath ? typePath.get('value').node : null;
|
||||
};
|
||||
|
||||
const parseModifiers = (value: t.ArrayExpression): string[] => (
|
||||
const parseModifiers = (value: any): string[] => (
|
||||
t.isArrayExpression(value)
|
||||
? value.elements
|
||||
.map((el) => (t.isStringLiteral(el) ? el.value : ''))
|
||||
@ -64,37 +64,38 @@ const parseDirectives = (params: {
|
||||
const shouldResolve = !['html', 'text', 'model', 'models'].includes(directiveName)
|
||||
|| (isVModel && !isComponent);
|
||||
|
||||
if (['models', 'model'].includes(directiveName)) {
|
||||
if (t.isArrayExpression(value)) {
|
||||
const elementsList = isVModels ? value.elements! : [value];
|
||||
let modifiers = underscoreModifiers;
|
||||
|
||||
elementsList.forEach((element) => {
|
||||
if (isVModels && !t.isArrayExpression(element)) {
|
||||
throw new Error('You should pass a Two-dimensional Arrays to v-models');
|
||||
}
|
||||
if (t.isArrayExpression(value)) {
|
||||
const elementsList = isVModels ? value.elements! : [value];
|
||||
|
||||
const { elements } = element as t.ArrayExpression;
|
||||
const [first, second, third] = elements;
|
||||
let modifiers = underscoreModifiers;
|
||||
elementsList.forEach((element) => {
|
||||
if (isVModels && !t.isArrayExpression(element)) {
|
||||
throw new Error('You should pass a Two-dimensional Arrays to v-models');
|
||||
}
|
||||
|
||||
if (second && !t.isArrayExpression(second) && !t.isSpreadElement(second)) {
|
||||
args.push(second);
|
||||
modifiers = parseModifiers(third as t.ArrayExpression);
|
||||
} else if (t.isArrayExpression(second)) {
|
||||
args.push(t.nullLiteral());
|
||||
modifiers = parseModifiers(second);
|
||||
} else {
|
||||
// work as v-model={[value]} or v-models={[[value]]}
|
||||
const { elements } = element as t.ArrayExpression;
|
||||
const [first, second, third] = elements;
|
||||
|
||||
if (second && !t.isArrayExpression(second) && !t.isSpreadElement(second)) {
|
||||
args.push(second);
|
||||
modifiers = parseModifiers(third as t.ArrayExpression);
|
||||
} else if (t.isArrayExpression(second)) {
|
||||
if (!shouldResolve) {
|
||||
args.push(t.nullLiteral());
|
||||
}
|
||||
modifiersSet.push(new Set(modifiers));
|
||||
vals.push(first as t.Expression);
|
||||
});
|
||||
} else if (isVModel) {
|
||||
// work as v-model={value}
|
||||
args.push(t.nullLiteral());
|
||||
modifiersSet.push(new Set(underscoreModifiers));
|
||||
}
|
||||
modifiers = parseModifiers(second);
|
||||
} else if (!shouldResolve) {
|
||||
// work as v-model={[value]} or v-models={[[value]]}
|
||||
args.push(t.nullLiteral());
|
||||
}
|
||||
modifiersSet.push(new Set(modifiers));
|
||||
vals.push(first as t.Expression);
|
||||
});
|
||||
} else if (isVModel && !shouldResolve) {
|
||||
// work as v-model={value}
|
||||
args.push(t.nullLiteral());
|
||||
modifiersSet.push(new Set(underscoreModifiers));
|
||||
} else {
|
||||
modifiersSet.push(new Set(underscoreModifiers));
|
||||
}
|
||||
@ -107,7 +108,9 @@ const parseDirectives = (params: {
|
||||
directive: shouldResolve ? [
|
||||
resolveDirective(path, state, tag, directiveName),
|
||||
vals[0] || value,
|
||||
!!modifiersSet[0]?.size && t.unaryExpression('void', t.numericLiteral(0), true),
|
||||
modifiersSet[0]?.size
|
||||
? args[0] || t.unaryExpression('void', t.numericLiteral(0), true)
|
||||
: args[0],
|
||||
!!modifiersSet[0]?.size && t.objectExpression(
|
||||
[...modifiersSet[0]].map(
|
||||
(modifier) => t.objectProperty(
|
||||
@ -116,7 +119,7 @@ const parseDirectives = (params: {
|
||||
),
|
||||
),
|
||||
),
|
||||
].filter(Boolean as any as ExcludesBoolean) : undefined,
|
||||
].filter(Boolean) as t.Expression[] : undefined,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -36,6 +36,24 @@ exports[`custom directive: custom directive 1`] = `
|
||||
_withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"cus\\"), x]]);"
|
||||
`;
|
||||
|
||||
exports[`custom directive: custom directive 2`] = `
|
||||
"import { withDirectives as _withDirectives, createVNode as _createVNode, resolveDirective as _resolveDirective, resolveComponent as _resolveComponent, Fragment as _Fragment } from \\"vue\\";
|
||||
|
||||
_createVNode(_Fragment, null, [_withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"xxx\\"), x]]), _withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"xxx\\"), x]]), _withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"xxx\\"), x, 'y']]), _withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"xxx\\"), x, 'y', {
|
||||
a: true,
|
||||
b: true
|
||||
}]]), _withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"xxx\\"), x, void 0, {
|
||||
a: true,
|
||||
b: true
|
||||
}]]), _withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"xxx\\"), x, y, {
|
||||
a: true,
|
||||
b: true
|
||||
}]]), _withDirectives(_createVNode(_resolveComponent(\\"A\\"), null, null, 512), [[_resolveDirective(\\"xxx\\"), x, y, {
|
||||
a: true,
|
||||
b: true
|
||||
}]])]);"
|
||||
`;
|
||||
|
||||
exports[`disable object slot syntax with defaultSlot: defaultSlot 1`] = `
|
||||
"import { createVNode as _createVNode, resolveComponent as _resolveComponent } from \\"vue\\";
|
||||
|
||||
|
@ -257,32 +257,6 @@ describe('Transform JSX', () => {
|
||||
});
|
||||
|
||||
describe('directive', () => {
|
||||
test('custom', () => {
|
||||
const calls: number[] = [];
|
||||
const customDirective = {
|
||||
mounted() {
|
||||
calls.push(1);
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount({
|
||||
directives: { custom: customDirective },
|
||||
setup() {
|
||||
return () => (
|
||||
<a
|
||||
v-custom={{
|
||||
value: 123,
|
||||
modifiers: { modifier: true },
|
||||
arg: 'arg',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
||||
const node = wrapper.vm.$.subTree;
|
||||
expect(calls).toEqual(expect.arrayContaining([1]));
|
||||
expect(node.dirs).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('vHtml', () => {
|
||||
const wrapper = shallowMount({
|
||||
setup() {
|
||||
|
@ -139,6 +139,20 @@ const transpile = (
|
||||
a = <A>{a}</A>;
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'custom directive',
|
||||
from: `
|
||||
<>
|
||||
<A v-xxx={x} />
|
||||
<A v-xxx={[x]} />
|
||||
<A v-xxx={[x, 'y']} />
|
||||
<A v-xxx={[x, 'y', ['a', 'b']]} />
|
||||
<A v-xxx={[x, ['a', 'b']]} />
|
||||
<A v-xxx={[x, y, ['a', 'b']]} />
|
||||
<A v-xxx={[x, y, ['a', 'b']]} />
|
||||
</>
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'vModels',
|
||||
from: '<C v-models={[[foo, ["modifier"]], [bar, "bar", ["modifier1", "modifier2"]]]} />',
|
||||
|
Loading…
Reference in New Issue
Block a user