mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 14:15:13 +00:00
fix(vue-app): fix asyncData
memory leak on client-side (#4966)
Co-authored-by: Sébastien Chopin <seb@chopin.io>
This commit is contained in:
parent
17cc12f005
commit
408680046c
@ -1,7 +1,5 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
const noopData = () => ({})
|
|
||||||
|
|
||||||
// window.{{globals.loadedCallback}} hook
|
// window.{{globals.loadedCallback}} hook
|
||||||
// Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading)
|
// Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading)
|
||||||
if (process.client) {
|
if (process.client) {
|
||||||
@ -24,12 +22,17 @@ export function interopDefault(promise) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function applyAsyncData(Component, asyncData) {
|
export function applyAsyncData(Component, asyncData) {
|
||||||
const ComponentData = Component.options.data || noopData
|
if (
|
||||||
// Prevent calling this method for each request on SSR context
|
// For SSR, we once all this function without second param to just apply asyncData
|
||||||
if (!asyncData && Component.options.hasAsyncData) {
|
// Prevent doing this for each SSR request
|
||||||
|
!asyncData && Component.options.__hasNuxtData
|
||||||
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Component.options.hasAsyncData = true
|
|
||||||
|
const ComponentData = Component.options._originDataFn || Component.options.data || function () { return {} }
|
||||||
|
Component.options._originDataFn = ComponentData
|
||||||
|
|
||||||
Component.options.data = function () {
|
Component.options.data = function () {
|
||||||
const data = ComponentData.call(this)
|
const data = ComponentData.call(this)
|
||||||
if (this.$ssrContext) {
|
if (this.$ssrContext) {
|
||||||
@ -37,6 +40,9 @@ export function applyAsyncData(Component, asyncData) {
|
|||||||
}
|
}
|
||||||
return { ...data, ...asyncData }
|
return { ...data, ...asyncData }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.options.__hasNuxtData = true
|
||||||
|
|
||||||
if (Component._Ctor && Component._Ctor.options) {
|
if (Component._Ctor && Component._Ctor.options) {
|
||||||
Component._Ctor.options.data = Component.options.data
|
Component._Ctor.options.data = Component.options.data
|
||||||
}
|
}
|
||||||
|
20
test/fixtures/spa/pages/async.vue
vendored
Normal file
20
test/fixtures/spa/pages/async.vue
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<pre>
|
||||||
|
{{ debug }}
|
||||||
|
</pre>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
asyncData() {
|
||||||
|
return {
|
||||||
|
[Math.random()]: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
debug() {
|
||||||
|
return JSON.stringify(this.$data, null, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -82,6 +82,23 @@ describe('spa', () => {
|
|||||||
expect(consola.log).toHaveBeenCalledWith('mounted')
|
expect(consola.log).toHaveBeenCalledWith('mounted')
|
||||||
consola.log.mockClear()
|
consola.log.mockClear()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('/async no asyncData leak', async () => {
|
||||||
|
const window = await nuxt.server.renderAndGetWindow(url('/async'))
|
||||||
|
|
||||||
|
const navigate = url => new Promise((resolve, reject) => {
|
||||||
|
window.$nuxt.$router.push(url, resolve, reject)
|
||||||
|
})
|
||||||
|
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
await navigate('/')
|
||||||
|
await navigate('/async')
|
||||||
|
}
|
||||||
|
|
||||||
|
const { $data } = window.$nuxt.$route.matched[0].instances.default
|
||||||
|
expect(Object.keys($data).length).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await nuxt.close()
|
await nuxt.close()
|
||||||
|
Loading…
Reference in New Issue
Block a user