mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-24 14:45:15 +00:00
fix(vue-app): prevent double page mount (#10874)
This commit is contained in:
parent
5441c062fa
commit
1f663e7f27
@ -649,7 +649,8 @@ function normalizeComponents (to, ___) {
|
||||
}
|
||||
|
||||
<% if (features.layouts) { %>
|
||||
<% if (splitChunks.layouts) { %>async <% } %>function setLayoutForNextPage (to) {
|
||||
const routeMap = new WeakMap()
|
||||
<% if (splitChunks.layouts) { %>async <% } %>function getLayoutForNextPage (to, from, next) {
|
||||
// Set layout
|
||||
let hasError = Boolean(this.$options.nuxt.err)
|
||||
if (this._hadError && this._dateLastError === this.$options.nuxt.dateErr) {
|
||||
@ -662,9 +663,19 @@ function normalizeComponents (to, ___) {
|
||||
if (typeof layout === 'function') {
|
||||
layout = layout(app.context)
|
||||
}
|
||||
|
||||
routeMap.set(to, layout);
|
||||
|
||||
<% if (splitChunks.layouts) { %>
|
||||
await this.loadLayout(layout)
|
||||
<% } %>
|
||||
if (next) next();
|
||||
}
|
||||
|
||||
function setLayoutForNextPage(to) {
|
||||
const layout = routeMap.get(to)
|
||||
routeMap.delete(to)
|
||||
|
||||
this.setLayout(layout)
|
||||
}
|
||||
<% } %>
|
||||
@ -903,6 +914,7 @@ async function mountApp (__app) {
|
||||
// Add afterEach router hooks
|
||||
router.afterEach(normalizeComponents)
|
||||
<% if (features.layouts) { %>
|
||||
router.beforeResolve(getLayoutForNextPage.bind(_app))
|
||||
router.afterEach(setLayoutForNextPage.bind(_app))
|
||||
<% } %>
|
||||
router.afterEach(fixPrepatch.bind(_app))
|
||||
@ -963,10 +975,15 @@ async function mountApp (__app) {
|
||||
}
|
||||
<% } %>
|
||||
|
||||
const clientFirstLayoutSet = <% if (splitChunks.layouts) { %>async<% } %> () => {
|
||||
<% if (splitChunks.layouts) { %>await<% } %> getLayoutForNextPage.call(_app, router.currentRoute)
|
||||
setLayoutForNextPage.call(_app, router.currentRoute)
|
||||
}
|
||||
|
||||
// First render on client-side
|
||||
const clientFirstMount = () => {
|
||||
normalizeComponents(router.currentRoute, router.currentRoute)
|
||||
setLayoutForNextPage.call(_app, router.currentRoute)
|
||||
clientFirstLayoutSet()
|
||||
checkForErrors(_app)
|
||||
// Don't call fixPrepatch.call(_app, router.currentRoute, router.currentRoute) since it's first render
|
||||
mount()
|
||||
|
@ -26,14 +26,14 @@ describe('nuxt basic resources size limit', () => {
|
||||
const LEGACY_JS_RESOURCES_GZIP_KB_SIZE = 88
|
||||
expect(legacyResourcesSize.gzip).toBeWithinSize(LEGACY_JS_RESOURCES_GZIP_KB_SIZE)
|
||||
|
||||
const LEGACY_JS_RESOURCES_BROTLI_KB_SIZE = 73
|
||||
const LEGACY_JS_RESOURCES_BROTLI_KB_SIZE = 76
|
||||
expect(legacyResourcesSize.brotli).toBeWithinSize(LEGACY_JS_RESOURCES_BROTLI_KB_SIZE)
|
||||
})
|
||||
|
||||
it('should stay within the size limit range in modern mode', async () => {
|
||||
const modernResourcesSize = await getResourcesSize(distDir, 'modern', { gzip: true, brotli: true })
|
||||
|
||||
const MODERN_JS_RESOURCES_KB_SIZE = 215
|
||||
const MODERN_JS_RESOURCES_KB_SIZE = 225
|
||||
expect(modernResourcesSize.uncompressed).toBeWithinSize(MODERN_JS_RESOURCES_KB_SIZE)
|
||||
|
||||
const MODERN_JS_RESOURCES_GZIP_KB_SIZE = 77
|
||||
|
60
test/e2e/page-mount-with-layouts.test.js
Normal file
60
test/e2e/page-mount-with-layouts.test.js
Normal file
@ -0,0 +1,60 @@
|
||||
import Browser from '../utils/browser'
|
||||
import { loadFixture, getPort, Nuxt } from '../utils'
|
||||
|
||||
let port
|
||||
const browser = new Browser()
|
||||
const url = route => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
let page = null
|
||||
|
||||
describe('page mount times while changing layouts', () => {
|
||||
beforeAll(async () => {
|
||||
const config = await loadFixture('page-mount-with-layouts')
|
||||
nuxt = new Nuxt(config)
|
||||
await nuxt.ready()
|
||||
|
||||
port = await getPort()
|
||||
await nuxt.server.listen(port, 'localhost')
|
||||
await browser.start()
|
||||
page = await browser.page(url('/page-1'))
|
||||
})
|
||||
|
||||
test('Open /page-1 and mount 1 times', async () => {
|
||||
expect(await page.$text('h1')).toBe('Layout 1')
|
||||
expect(await page.$text('h2')).toBe('Page 1')
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(1)
|
||||
})
|
||||
|
||||
test('Change layout and mount 2 times', async () => {
|
||||
page = await browser.page(url('/page-1'))
|
||||
|
||||
await page.nuxt.navigate('/page-2')
|
||||
|
||||
expect(await page.$text('h1')).toBe('Layout 2')
|
||||
expect(await page.$text('h2')).toBe('Page 2')
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(2)
|
||||
})
|
||||
|
||||
test('Change layout multiple times', async () => {
|
||||
page = await browser.page(url('/page-2'))
|
||||
|
||||
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)
|
||||
|
||||
await page.nuxt.navigate('/page-2')
|
||||
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(3)
|
||||
|
||||
await page.nuxt.navigate('/page-1')
|
||||
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(4)
|
||||
|
||||
await page.nuxt.navigate('/page-1', false)
|
||||
|
||||
expect(await page.evaluate(() => window.mountedCount)).toEqual(4)
|
||||
})
|
||||
})
|
7
test/fixtures/page-mount-with-layouts/layouts/layout-1.vue
vendored
Normal file
7
test/fixtures/page-mount-with-layouts/layouts/layout-1.vue
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Layout 1</h1>
|
||||
|
||||
<Nuxt />
|
||||
</div>
|
||||
</template>
|
7
test/fixtures/page-mount-with-layouts/layouts/layout-2.vue
vendored
Normal file
7
test/fixtures/page-mount-with-layouts/layouts/layout-2.vue
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Layout 2</h1>
|
||||
|
||||
<Nuxt />
|
||||
</div>
|
||||
</template>
|
11
test/fixtures/page-mount-with-layouts/nuxt.config.js
vendored
Normal file
11
test/fixtures/page-mount-with-layouts/nuxt.config.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
export default {
|
||||
features: {
|
||||
transitions: false
|
||||
},
|
||||
|
||||
build: {
|
||||
splitChunks: {
|
||||
layouts: true
|
||||
}
|
||||
}
|
||||
}
|
3
test/fixtures/page-mount-with-layouts/page-mount-with-layouts.test.js
vendored
Normal file
3
test/fixtures/page-mount-with-layouts/page-mount-with-layouts.test.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { buildFixture } from '../../utils/build'
|
||||
|
||||
buildFixture('page-mount-with-layouts')
|
22
test/fixtures/page-mount-with-layouts/pages/page-1.vue
vendored
Normal file
22
test/fixtures/page-mount-with-layouts/pages/page-1.vue
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Page 1</h2>
|
||||
|
||||
<NuxtLink
|
||||
id="link"
|
||||
to="/page-2"
|
||||
>
|
||||
To page 2
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
layout: 'layout-1',
|
||||
|
||||
mounted () {
|
||||
window.mountedCount = (window.mountedCount || 0) + 1
|
||||
}
|
||||
}
|
||||
</script>
|
22
test/fixtures/page-mount-with-layouts/pages/page-2.vue
vendored
Normal file
22
test/fixtures/page-mount-with-layouts/pages/page-2.vue
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Page 2</h2>
|
||||
|
||||
<NuxtLink
|
||||
id="link"
|
||||
to="/page-1"
|
||||
>
|
||||
To page 1
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
layout: 'layout-2',
|
||||
|
||||
mounted () {
|
||||
window.mountedCount = (window.mountedCount || 0) + 1
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user