feat: don't resolve directives in scope

This commit is contained in:
Kael 2025-02-20 17:52:46 +11:00
parent 2f75d2f872
commit e6cee1ab58
4 changed files with 53 additions and 1 deletions

View File

@ -184,6 +184,11 @@ const resolveDirective = (
}
return modelToUse;
}
const referenceName =
'v' + directiveName[0].toUpperCase() + directiveName.slice(1);
if (path.scope.references[referenceName]) {
return t.identifier(referenceName);
}
return t.callExpression(createIdentifier(state, 'resolveDirective'), [
t.stringLiteral(directiveName),
]);

View File

@ -407,7 +407,15 @@ const transformJSXElement = (
// #541 - directives can't be resolved in optimized slots
// all parents should be deoptimized
if (directives.length) {
if (
directives.length &&
directives.some(
(d) =>
d.elements?.[0]?.type === 'CallExpression' &&
d.elements[0].callee.type === 'Identifier' &&
d.elements[0].callee.name === '_resolveDirective'
)
) {
let currentPath = path;
while (currentPath.parentPath?.isJSXElement()) {
currentPath = currentPath.parentPath;

View File

@ -63,6 +63,12 @@ _createVNode(_Fragment, null, [_withDirectives(_createVNode(_resolveComponent("A
}]])]);"
`;
exports[`directive in scope > directive in scope 1`] = `
"import { resolveComponent as _resolveComponent, createVNode as _createVNode, withDirectives as _withDirectives } from "vue";
const vXxx = {};
_withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[vXxx]]);"
`;
exports[`disable object slot syntax with defaultSlot > defaultSlot 1`] = `
"import { resolveComponent as _resolveComponent, createVNode as _createVNode } from "vue";
_createVNode(_resolveComponent("Badge"), null, {
@ -164,6 +170,20 @@ _createVNode(_Fragment, null, [_createVNode(_resolveComponent("A"), null, {
})]);"
`;
exports[`passing object slots via JSX children directive in slot, in scope > directive in slot, in scope 1`] = `
"import { Fragment as _Fragment, createVNode as _createVNode, withDirectives as _withDirectives, resolveComponent as _resolveComponent } from "vue";
const vXxx = {};
_createVNode(_Fragment, null, [_createVNode(_resolveComponent("A"), null, {
default: () => [_withDirectives(_createVNode("div", null, null, 512), [[vXxx]]), foo],
_: 1
}), _createVNode(_resolveComponent("A"), null, {
default: () => [_createVNode(_resolveComponent("B"), null, {
default: () => [_withDirectives(_createVNode("div", null, null, 512), [[vXxx]]), foo],
_: 1
})]
})]);"
`;
exports[`passing object slots via JSX children multiple expressions > multiple expressions 1`] = `
"import { resolveComponent as _resolveComponent, createVNode as _createVNode } from "vue";
_createVNode(_resolveComponent("A"), null, {

View File

@ -155,6 +155,13 @@ const transpile = (source: string, options: VueJSXPluginOptions = {}) =>
</>
`,
},
{
name: 'directive in scope',
from: `
const vXxx = {};
<A v-xxx />
`,
},
{
name: 'vModels',
from: '<C v-models={[[foo, ["modifier"]], [bar, "bar", ["modifier1", "modifier2"]]]} />',
@ -277,6 +284,18 @@ const slotsTests: Test[] = [
</>
`,
},
{
name: 'directive in slot, in scope',
from: `
const vXxx = {};
<>
<A><div v-xxx />{foo}</A>
<A>
<B><div v-xxx />{foo}</B>
</A>
</>
`,
},
];
slotsTests.forEach(({ name, from }) => {