mirror of
https://github.com/nuxt/nuxt.git
synced 2024-12-01 01:47:11 +00:00
fix(vue-app): prevent error page mounting twice (#27484)
This commit is contained in:
parent
e0ca3d1af8
commit
db15c3ab61
@ -244,6 +244,7 @@ export default {
|
||||
<% if (splitChunks.layouts) { %>
|
||||
await this.loadLayout(errorLayout)
|
||||
<% } %>
|
||||
this.nuxt.errPageReady = true
|
||||
this.setLayout(errorLayout)
|
||||
}
|
||||
},
|
||||
|
@ -676,6 +676,12 @@ function setLayoutForNextPage(to) {
|
||||
const layout = routeMap.get(to)
|
||||
routeMap.delete(to)
|
||||
|
||||
const prevPageIsError = this._hadError && this._dateLastError === this.$options.nuxt.dateErr
|
||||
|
||||
if (prevPageIsError) {
|
||||
this.$options.nuxt.err = null
|
||||
}
|
||||
|
||||
this.setLayout(layout)
|
||||
}
|
||||
<% } %>
|
||||
@ -946,6 +952,7 @@ async function mountApp (__app) {
|
||||
_app.$loading = {} // To avoid error while _app.$nuxt does not exist
|
||||
if (NUXT.error) {
|
||||
_app.error(NUXT.error)
|
||||
_app.nuxt.errPageReady = true
|
||||
}
|
||||
|
||||
// Add beforeEach router hooks
|
||||
|
@ -74,8 +74,9 @@ export default {
|
||||
Vue.util.defineReactive(this, 'nuxt', this.$root.$options.nuxt)
|
||||
},
|
||||
render (h) {
|
||||
// if there is no error
|
||||
if (!this.nuxt.err) {
|
||||
// if there is no error or
|
||||
// error page has not been loaded yet on client
|
||||
if (!this.nuxt.err || (process.client && !this.nuxt.errPageReady)) {
|
||||
// Directly return nuxt child
|
||||
return h('NuxtChild', {
|
||||
key: this.routerViewKey,
|
||||
|
@ -139,6 +139,7 @@ async function createApp(ssrContext, config = {}) {
|
||||
},
|
||||
<% } %>
|
||||
err: null,
|
||||
errPageReady: false,
|
||||
dateErr: null,
|
||||
error (err) {
|
||||
err = err || null
|
||||
@ -150,6 +151,7 @@ async function createApp(ssrContext, config = {}) {
|
||||
}
|
||||
nuxt.dateErr = Date.now()
|
||||
nuxt.err = err
|
||||
nuxt.errPageReady = false
|
||||
// Used in src/server.js
|
||||
if (ssrContext) {
|
||||
ssrContext.nuxt.error = err
|
||||
|
@ -57,4 +57,40 @@ describe('page mount times while changing layouts', () => {
|
||||
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(4)
|
||||
})
|
||||
|
||||
test('Open 404 error-page and mount 1 times', async () => {
|
||||
page = await browser.page(url('/404'))
|
||||
|
||||
expect(await page.$text('h1')).toBe('Layout error')
|
||||
expect(await page.$text('h2')).toBe('Error page 404')
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(1)
|
||||
})
|
||||
|
||||
test('Open another error-page and mount 1 times', async () => {
|
||||
page = await browser.page(url('/403'))
|
||||
|
||||
expect(await page.$text('h1')).toBe('Layout error')
|
||||
expect(await page.$text('h2')).toBe('Error page 403')
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(1)
|
||||
})
|
||||
|
||||
test('Change error layout to common', async () => {
|
||||
page = await browser.page(url('/404'))
|
||||
|
||||
await page.nuxt.navigate('/page-1')
|
||||
|
||||
expect(await page.$text('h1')).toBe('Layout 1')
|
||||
expect(await page.$text('h2')).toBe('Page 1')
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(2)
|
||||
})
|
||||
|
||||
test('Change common layout to error', async () => {
|
||||
page = await browser.page(url('/page-1'))
|
||||
|
||||
await page.nuxt.navigate('/404')
|
||||
|
||||
expect(await page.$text('h1')).toBe('Layout error')
|
||||
expect(await page.$text('h2')).toBe('Error page 404')
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(2)
|
||||
})
|
||||
})
|
||||
|
22
test/fixtures/page-mount-with-layouts/layouts/error.vue
vendored
Normal file
22
test/fixtures/page-mount-with-layouts/layouts/error.vue
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Error page {{ error.statusCode }}</h2>
|
||||
|
||||
<NuxtLink
|
||||
id="link"
|
||||
to="/page-1"
|
||||
>
|
||||
To page 1
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
layout: 'layout-error',
|
||||
props: ['error'],
|
||||
mounted () {
|
||||
window.mountedCount = (window.mountedCount || 0) + 1
|
||||
}
|
||||
}
|
||||
</script>
|
7
test/fixtures/page-mount-with-layouts/layouts/layout-error.vue
vendored
Normal file
7
test/fixtures/page-mount-with-layouts/layouts/layout-error.vue
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Layout error</h1>
|
||||
|
||||
<Nuxt />
|
||||
</div>
|
||||
</template>
|
11
test/fixtures/page-mount-with-layouts/pages/403.vue
vendored
Normal file
11
test/fixtures/page-mount-with-layouts/pages/403.vue
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData ({ error }) {
|
||||
return error({ statusCode: 403 })
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user