From 021006680e7d37f0f4aaa1bfe7de8a4692f2eb9e Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 23 Mar 2021 18:28:44 +0000 Subject: [PATCH] fix: use wrapper for lazy-loaded functional components (#172) Co-authored-by: pooya parsa --- templates/components/index.js | 33 +++++++++++++++++++++- templates/components/plugin.js | 4 ++- test/fixture/my-lib/components/MAwesome.js | 2 +- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/templates/components/index.js b/templates/components/index.js index 8e60510..8951c1c 100644 --- a/templates/components/index.js +++ b/templates/components/index.js @@ -5,5 +5,36 @@ <%= options.getComponents().map(c => { const exp = c.export === 'default' ? `c.default || c` : `c['${c.export}']` - return `export const Lazy${c.pascalName} = import('../${relativeToBuild(c.filePath)}' /* webpackChunkName: "${c.chunkName}" */).then(c => ${exp})` + return `export const Lazy${c.pascalName} = import('../${relativeToBuild(c.filePath)}' /* webpackChunkName: "${c.chunkName}" */).then(c => wrapFunctional(${exp}))` }).join('\n') %> + +// nuxt/nuxt.js#8607 +export function wrapFunctional(options) { + if (!options || !options.functional) { + return options + } + + const propKeys = Array.isArray(options.props) ? options.props : Object.keys(options.props || {}) + + return { + render(h) { + const attrs = {} + const props = {} + + for (const key in this.$attrs) { + if (propKeys.includes(key)) { + props[key] = this.$attrs[key] + } else { + attrs[key] = this.$attrs[key] + } + } + + return h(options, { + on: this.$listeners, + attrs, + props, + scopedSlots: this.$scopedSlots, + }, this.$slots.default) + } + } +} diff --git a/templates/components/plugin.js b/templates/components/plugin.js index 1892b88..0c96e93 100644 --- a/templates/components/plugin.js +++ b/templates/components/plugin.js @@ -1,10 +1,12 @@ import Vue from 'vue' +import { wrapFunctional } from './index' + <% const components = options.getComponents() %> const components = { <%= components.map(c => { const exp = c.export === 'default' ? `c.default || c` : `c['${c.export}']` - return ` ${c.pascalName.replace(/^Lazy/, '')}: () => import('../${relativeToBuild(c.filePath)}' /* webpackChunkName: "${c.chunkName}" */).then(c => ${exp})` + return ` ${c.pascalName.replace(/^Lazy/, '')}: () => import('../${relativeToBuild(c.filePath)}' /* webpackChunkName: "${c.chunkName}" */).then(c => wrapFunctional(${exp}))` }).join(',\n') %> } diff --git a/test/fixture/my-lib/components/MAwesome.js b/test/fixture/my-lib/components/MAwesome.js index 3fc8723..4e3c62a 100644 --- a/test/fixture/my-lib/components/MAwesome.js +++ b/test/fixture/my-lib/components/MAwesome.js @@ -1,4 +1,4 @@ // @vue/component -export const MAwesome = { +export const MMAwesome = { render: h => h('div', 'M is Awesome!') }