diff --git a/src/core/vdom/helpers/resolve-async-component.js b/src/core/vdom/helpers/resolve-async-component.js index fa76090553c..534c444f2a2 100644 --- a/src/core/vdom/helpers/resolve-async-component.js +++ b/src/core/vdom/helpers/resolve-async-component.js @@ -53,7 +53,7 @@ export function resolveAsyncComponent ( } const owner = currentRenderingInstance - if (isDef(factory.owners) && factory.owners.indexOf(owner) === -1) { + if (owner && isDef(factory.owners) && factory.owners.indexOf(owner) === -1) { // already pending factory.owners.push(owner) } @@ -62,7 +62,7 @@ export function resolveAsyncComponent ( return factory.loadingComp } - if (!isDef(factory.owners)) { + if (owner && !isDef(factory.owners)) { const owners = factory.owners = [owner] let sync = true diff --git a/test/ssr/ssr-string.spec.js b/test/ssr/ssr-string.spec.js index 19bc4005419..e18ca2aead9 100644 --- a/test/ssr/ssr-string.spec.js +++ b/test/ssr/ssr-string.spec.js @@ -640,6 +640,41 @@ describe('SSR: renderToString', () => { }) }) + it('renders nested async functional component', done => { + renderVmWithOptions({ + template: ` +
+ +
+ `, + components: { + outerAsync (resolve) { + setTimeout(() => resolve({ + functional: true, + render (h) { + return h('innerAsync') + } + }), 1) + }, + innerAsync (resolve) { + setTimeout(() => resolve({ + functional: true, + render (h) { + return h('span', { class: ['a'] }, 'inner') + }, + }), 1) + } + } + }, result => { + expect(result).toContain( + '
' + + 'inner' + + '
' + ) + done() + }) + }) + it('should catch async component error', done => { Vue.config.silent = true renderToString(new Vue({