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) => {
|
values.forEach((value, index) => {
|
||||||
const propName = args[index];
|
const propName = args[index];
|
||||||
// v-model target with variable
|
// v-model target with variable
|
||||||
// const isIdentifierProp = t.isIdentifier(propName);
|
const isDynamic = propName && !t.isStringLiteral(propName) && !t.isNullLiteral(propName);
|
||||||
const isDynamic = !t.isStringLiteral(propName) && !t.isNullLiteral(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) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as t from '@babel/types';
|
import * as t from '@babel/types';
|
||||||
import { NodePath } from '@babel/traverse';
|
import { NodePath } from '@babel/traverse';
|
||||||
import { createIdentifier } from './utils';
|
import { createIdentifier } from './utils';
|
||||||
import { State, ExcludesBoolean } from '.';
|
import { State } from '.';
|
||||||
|
|
||||||
export type Tag = t.Identifier | t.MemberExpression | t.StringLiteral | t.CallExpression;
|
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;
|
return typePath ? typePath.get('value').node : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseModifiers = (value: t.ArrayExpression): string[] => (
|
const parseModifiers = (value: any): string[] => (
|
||||||
t.isArrayExpression(value)
|
t.isArrayExpression(value)
|
||||||
? value.elements
|
? value.elements
|
||||||
.map((el) => (t.isStringLiteral(el) ? el.value : ''))
|
.map((el) => (t.isStringLiteral(el) ? el.value : ''))
|
||||||
@ -64,37 +64,38 @@ const parseDirectives = (params: {
|
|||||||
const shouldResolve = !['html', 'text', 'model', 'models'].includes(directiveName)
|
const shouldResolve = !['html', 'text', 'model', 'models'].includes(directiveName)
|
||||||
|| (isVModel && !isComponent);
|
|| (isVModel && !isComponent);
|
||||||
|
|
||||||
if (['models', 'model'].includes(directiveName)) {
|
let modifiers = underscoreModifiers;
|
||||||
if (t.isArrayExpression(value)) {
|
|
||||||
const elementsList = isVModels ? value.elements! : [value];
|
|
||||||
|
|
||||||
elementsList.forEach((element) => {
|
if (t.isArrayExpression(value)) {
|
||||||
if (isVModels && !t.isArrayExpression(element)) {
|
const elementsList = isVModels ? value.elements! : [value];
|
||||||
throw new Error('You should pass a Two-dimensional Arrays to v-models');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { elements } = element as t.ArrayExpression;
|
elementsList.forEach((element) => {
|
||||||
const [first, second, third] = elements;
|
if (isVModels && !t.isArrayExpression(element)) {
|
||||||
let modifiers = underscoreModifiers;
|
throw new Error('You should pass a Two-dimensional Arrays to v-models');
|
||||||
|
}
|
||||||
|
|
||||||
if (second && !t.isArrayExpression(second) && !t.isSpreadElement(second)) {
|
const { elements } = element as t.ArrayExpression;
|
||||||
args.push(second);
|
const [first, second, third] = elements;
|
||||||
modifiers = parseModifiers(third as t.ArrayExpression);
|
|
||||||
} else if (t.isArrayExpression(second)) {
|
if (second && !t.isArrayExpression(second) && !t.isSpreadElement(second)) {
|
||||||
args.push(t.nullLiteral());
|
args.push(second);
|
||||||
modifiers = parseModifiers(second);
|
modifiers = parseModifiers(third as t.ArrayExpression);
|
||||||
} else {
|
} else if (t.isArrayExpression(second)) {
|
||||||
// work as v-model={[value]} or v-models={[[value]]}
|
if (!shouldResolve) {
|
||||||
args.push(t.nullLiteral());
|
args.push(t.nullLiteral());
|
||||||
}
|
}
|
||||||
modifiersSet.push(new Set(modifiers));
|
modifiers = parseModifiers(second);
|
||||||
vals.push(first as t.Expression);
|
} else if (!shouldResolve) {
|
||||||
});
|
// work as v-model={[value]} or v-models={[[value]]}
|
||||||
} else if (isVModel) {
|
args.push(t.nullLiteral());
|
||||||
// work as v-model={value}
|
}
|
||||||
args.push(t.nullLiteral());
|
modifiersSet.push(new Set(modifiers));
|
||||||
modifiersSet.push(new Set(underscoreModifiers));
|
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 {
|
} else {
|
||||||
modifiersSet.push(new Set(underscoreModifiers));
|
modifiersSet.push(new Set(underscoreModifiers));
|
||||||
}
|
}
|
||||||
@ -107,7 +108,9 @@ const parseDirectives = (params: {
|
|||||||
directive: shouldResolve ? [
|
directive: shouldResolve ? [
|
||||||
resolveDirective(path, state, tag, directiveName),
|
resolveDirective(path, state, tag, directiveName),
|
||||||
vals[0] || value,
|
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]?.size && t.objectExpression(
|
||||||
[...modifiersSet[0]].map(
|
[...modifiersSet[0]].map(
|
||||||
(modifier) => t.objectProperty(
|
(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]]);"
|
_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`] = `
|
exports[`disable object slot syntax with defaultSlot: defaultSlot 1`] = `
|
||||||
"import { createVNode as _createVNode, resolveComponent as _resolveComponent } from \\"vue\\";
|
"import { createVNode as _createVNode, resolveComponent as _resolveComponent } from \\"vue\\";
|
||||||
|
|
||||||
|
@ -257,32 +257,6 @@ describe('Transform JSX', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('directive', () => {
|
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', () => {
|
test('vHtml', () => {
|
||||||
const wrapper = shallowMount({
|
const wrapper = shallowMount({
|
||||||
setup() {
|
setup() {
|
||||||
|
@ -139,6 +139,20 @@ const transpile = (
|
|||||||
a = <A>{a}</A>;
|
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',
|
name: 'vModels',
|
||||||
from: '<C v-models={[[foo, ["modifier"]], [bar, "bar", ["modifier1", "modifier2"]]]} />',
|
from: '<C v-models={[[foo, ["modifier"]], [bar, "bar", ["modifier1", "modifier2"]]]} />',
|
||||||
|
Loading…
Reference in New Issue
Block a user