diff --git a/packages/babel-sugar-composition-api-render-instance/README.md b/packages/babel-sugar-composition-api-render-instance/README.md index c346c85..6f041ee 100644 --- a/packages/babel-sugar-composition-api-render-instance/README.md +++ b/packages/babel-sugar-composition-api-render-instance/README.md @@ -37,7 +37,9 @@ Input: ```jsx defineComponent({ - setup: () => <MyComponent vModel={a.b} /> + setup() { + return () => <MyComponent vModel={a.b} /> + } }) ``` @@ -45,12 +47,14 @@ Output (without @vue/babel-sugar-composition-api-render-instance): ```jsx defineComponent({ - setup: () => <MyComponent model={{ - value: a.b, - callback: $$v => { - this.$set(a, "b", $$v); - } - }} />; + setup() { + return () => <MyComponent model={{ + value: a.b, + callback: $$v => { + this.$set(a, "b", $$v); + } + }} /> + } }) ``` @@ -60,11 +64,15 @@ Output (with @vue/babel-sugar-composition-api-render-instance): import { getCurrentInstance } from "@vue/composition-api"; defineComponent({ - setup: () => <MyComponent model={{ - value: a.b, - callback: $$v => { - getCurrentInstance().$set(a, "b", $$v); - } - }} />; + setup() { + const __currentInstance = getCurrentInstance(); + + return () => <MyComponent model={{ + value: a.b, + callback: $$v => { + __currentInstance.$set(a, "b", $$v); + } + }} /> + } }) ``` diff --git a/packages/babel-sugar-composition-api-render-instance/src/index.js b/packages/babel-sugar-composition-api-render-instance/src/index.js index 0fb57a8..b214978 100644 --- a/packages/babel-sugar-composition-api-render-instance/src/index.js +++ b/packages/babel-sugar-composition-api-render-instance/src/index.js @@ -20,6 +20,8 @@ const autoImportGetCurrentInstance = (t, path) => { } } +const injectInstanceId = '__currentInstance' + export default ({ types: t }) => { return { inherits: syntaxJsx, @@ -30,6 +32,11 @@ export default ({ types: t }) => { if (path1.node.key.name !== 'setup') { return } + + let instanceInjected = false + + + path1.traverse({ JSXAttribute(path2) { const n = path2.get('name') @@ -41,7 +48,18 @@ export default ({ types: t }) => { const prop = path3.get('property') if (t.isThisExpression(obj) && t.isIdentifier(prop) && ['$', '_'].includes(prop.node.name[0])) { autoImportGetCurrentInstance(t, p) - obj.replaceWith(t.callExpression(t.identifier('getCurrentInstance'), [])) + if (!instanceInjected) { + path1.node.value.body.body.unshift( + t.variableDeclaration('const', [ + t.variableDeclarator( + t.identifier(injectInstanceId), + t.callExpression(t.identifier('getCurrentInstance'), []), + ), + ]), + ) + instanceInjected = true + } + obj.replaceWith(t.identifier(injectInstanceId)) } }, }) diff --git a/packages/babel-sugar-composition-api-render-instance/test/test.js b/packages/babel-sugar-composition-api-render-instance/test/test.js index 70bc303..f1f4959 100644 --- a/packages/babel-sugar-composition-api-render-instance/test/test.js +++ b/packages/babel-sugar-composition-api-render-instance/test/test.js @@ -34,51 +34,59 @@ const tests = [ { name: 'Ignores non vModel arguments', from: `const a = { setup: () => { return () => <A x="y" a:b={c} /> } }`, - to: `const a = { + to: ` +const a = { setup: () => { return () => <A x="y" a:b={c} />; } -};`, +};`.trim(), }, { name: 'Generic component vModel', from: `const a = { setup: () => { return () => <MyComponent vModel={a.b} /> } }`, - to: `import { getCurrentInstance } from "@vue/composition-api"; + to: ` +import { getCurrentInstance } from "@vue/composition-api"; const a = { setup: () => { + const __currentInstance = getCurrentInstance(); + return () => <MyComponent model={{ value: a.b, callback: $$v => { - getCurrentInstance().$set(a, "b", $$v); + __currentInstance.$set(a, "b", $$v); } }} />; } -};`, +};`.trim(), }, { name: 'Component vModel_number', from: `const a = { setup: () => { return () => <MyComponent vModel_number={a.b} /> } }`, - to: `import { getCurrentInstance } from "@vue/composition-api"; + to: ` +import { getCurrentInstance } from "@vue/composition-api"; const a = { setup: () => { + const __currentInstance = getCurrentInstance(); + return () => <MyComponent model={{ value: a.b, callback: $$v => { - getCurrentInstance().$set(a, "b", getCurrentInstance()._n($$v)); + __currentInstance.$set(a, "b", __currentInstance._n($$v)); } }} />; } -};`, +};`.trim(), }, { name: 'Ignore outside of setup()', from: `const A = <MyComponent vModel={a[b]} />`, - to: `const A = <MyComponent model={{ + to: ` +const A = <MyComponent model={{ value: a[b], callback: $$v => { this.$set(a, b, $$v); } -}} />;`, +}} />;`.trim(), }, ]