diff --git a/packages/babel-plugin-jsx/README.md b/packages/babel-plugin-jsx/README.md index ee375d9a..0b497c36 100644 --- a/packages/babel-plugin-jsx/README.md +++ b/packages/babel-plugin-jsx/README.md @@ -243,24 +243,29 @@ h(A, { #### custom directive -Recommended when using string arguments - ```jsx const App = { - directives: { custom: customDirective }, + directives: { custom: vCustom }, setup() { - return () => ; + return () => ; }, }; ``` +Directive names will resolve a variable matching `/v[A-Z]/` first, `options.directives` is only needed to prevent the import from being reported as unused. + +Arguments and modifiers can be added as an array: + ```jsx -const App = { - directives: { custom: customDirective }, - setup() { - return () => ; - }, -}; +// same as v-custom:arg.a.b="val" in a .vue file + +``` + +Or arguments as part of the attribute name: + +```jsx + + ``` ### Slot diff --git a/packages/babel-plugin-jsx/src/parseDirectives.ts b/packages/babel-plugin-jsx/src/parseDirectives.ts index ba23fb09..2d615fbc 100644 --- a/packages/babel-plugin-jsx/src/parseDirectives.ts +++ b/packages/babel-plugin-jsx/src/parseDirectives.ts @@ -186,9 +186,13 @@ const resolveDirective = ( } const referenceName = 'v' + directiveName[0].toUpperCase() + directiveName.slice(1); - if (path.scope.references[referenceName]) { - return t.identifier(referenceName); - } + let scope = path.scope; + do { + if (scope.references[referenceName]) { + return t.identifier(referenceName); + } + scope = scope.parent; + } while (scope); return t.callExpression(createIdentifier(state, 'resolveDirective'), [ t.stringLiteral(directiveName), ]); diff --git a/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap b/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap index c4c2f986..1e59a664 100644 --- a/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap +++ b/packages/babel-plugin-jsx/test/__snapshots__/snapshot.test.ts.snap @@ -63,6 +63,12 @@ _createVNode(_Fragment, null, [_withDirectives(_createVNode(_resolveComponent("A }]])]);" `; +exports[`directive in outer scope > directive in outer 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[`directive in scope > directive in scope 1`] = ` "import { resolveComponent as _resolveComponent, createVNode as _createVNode, withDirectives as _withDirectives } from "vue"; const vXxx = {}; diff --git a/packages/babel-plugin-jsx/test/snapshot.test.ts b/packages/babel-plugin-jsx/test/snapshot.test.ts index 00e92c9c..c3b80529 100644 --- a/packages/babel-plugin-jsx/test/snapshot.test.ts +++ b/packages/babel-plugin-jsx/test/snapshot.test.ts @@ -162,6 +162,15 @@ const transpile = (source: string, options: VueJSXPluginOptions = {}) => `, }, + { + name: 'directive in outer scope', + from: ` + const vXxx = {}; + () => ( + + ); + `, + }, { name: 'vModels', from: '',