mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-17 06:01:34 +00:00
feat(vue-app): context.beforeSerialize
method (#9332)
Co-authored-by: Sébastien Chopin <seb@nuxtjs.com> Co-authored-by: Daniel Roe <daniel@roe.dev> Co-authored-by: pooya parsa <pyapar@gmail.com>
This commit is contained in:
parent
fa12cf1e2d
commit
9f02e5dae7
2
packages/types/app/index.d.ts
vendored
2
packages/types/app/index.d.ts
vendored
@ -72,6 +72,7 @@ export interface Context {
|
|||||||
redirected: boolean
|
redirected: boolean
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
beforeRenderFns: Array<() => any>
|
beforeRenderFns: Array<() => any>
|
||||||
|
beforeSerializeFns: Array<() => any>
|
||||||
fetchCounters: Record<string, number>
|
fetchCounters: Record<string, number>
|
||||||
nuxt: {
|
nuxt: {
|
||||||
layout: string
|
layout: string
|
||||||
@ -87,6 +88,7 @@ export interface Context {
|
|||||||
error(params: NuxtError): void
|
error(params: NuxtError): void
|
||||||
nuxtState: NuxtState
|
nuxtState: NuxtState
|
||||||
beforeNuxtRender(fn: (params: { Components: VueRouter['getMatchedComponents'], nuxtState: NuxtState }) => void): void
|
beforeNuxtRender(fn: (params: { Components: VueRouter['getMatchedComponents'], nuxtState: NuxtState }) => void): void
|
||||||
|
beforeSerialize(fn: (nuxtState: NuxtState) => void): void
|
||||||
enablePreview?: (previewData?: Record<string, any>) => void
|
enablePreview?: (previewData?: Record<string, any>) => void
|
||||||
$preview?: Record<string, any>
|
$preview?: Record<string, any>
|
||||||
}
|
}
|
||||||
|
@ -183,6 +183,7 @@ async function createApp(ssrContext, config = {}) {
|
|||||||
req: ssrContext ? ssrContext.req : undefined,
|
req: ssrContext ? ssrContext.req : undefined,
|
||||||
res: ssrContext ? ssrContext.res : undefined,
|
res: ssrContext ? ssrContext.res : undefined,
|
||||||
beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined,
|
beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined,
|
||||||
|
beforeSerializeFns: ssrContext ? ssrContext.beforeSerializeFns : undefined,
|
||||||
ssrContext
|
ssrContext
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -85,6 +85,8 @@ export default async (ssrContext) => {
|
|||||||
ssrContext.next = createNext(ssrContext)
|
ssrContext.next = createNext(ssrContext)
|
||||||
// Used for beforeNuxtRender({ Components, nuxtState })
|
// Used for beforeNuxtRender({ Components, nuxtState })
|
||||||
ssrContext.beforeRenderFns = []
|
ssrContext.beforeRenderFns = []
|
||||||
|
// for beforeSerialize(nuxtState)
|
||||||
|
ssrContext.beforeSerializeFns = []
|
||||||
// Nuxt object (window.{{globals.context}}, defaults to window.__NUXT__)
|
// Nuxt object (window.{{globals.context}}, defaults to window.__NUXT__)
|
||||||
ssrContext.nuxt = { <% if (features.layouts) { %>layout: 'default', <% } %>data: [], <% if (features.fetch) { %>fetch: {}, <% } %>error: null<%= (store ? ', state: null' : '') %>, serverRendered: true, routePath: '' }
|
ssrContext.nuxt = { <% if (features.layouts) { %>layout: 'default', <% } %>data: [], <% if (features.fetch) { %>fetch: {}, <% } %>error: null<%= (store ? ', state: null' : '') %>, serverRendered: true, routePath: '' }
|
||||||
<% if (features.fetch) { %>
|
<% if (features.fetch) { %>
|
||||||
@ -120,16 +122,21 @@ export default async (ssrContext) => {
|
|||||||
const beforeRender = async () => {
|
const beforeRender = async () => {
|
||||||
// Call beforeNuxtRender() methods
|
// Call beforeNuxtRender() methods
|
||||||
await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt })))
|
await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt })))
|
||||||
<% if (store) { %>
|
|
||||||
ssrContext.rendered = () => {
|
ssrContext.rendered = () => {
|
||||||
|
// Call beforeSerialize() hooks
|
||||||
|
ssrContext.beforeSerializeFns.forEach(fn => fn(ssrContext.nuxt))
|
||||||
|
|
||||||
|
<% if (store) { %>
|
||||||
// Add the state from the vuex store
|
// Add the state from the vuex store
|
||||||
ssrContext.nuxt.state = store.state
|
ssrContext.nuxt.state = store.state
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<% if (isFullStatic && store) { %>
|
<% if (isFullStatic && store) { %>
|
||||||
// Stop recording store mutations
|
// Stop recording store mutations
|
||||||
ssrContext.unsetMutationObserver()
|
ssrContext.unsetMutationObserver()
|
||||||
<% } %>
|
<% } %>
|
||||||
}
|
}
|
||||||
<% } %>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderErrorPage = async () => {
|
const renderErrorPage = async () => {
|
||||||
|
@ -259,6 +259,7 @@ export async function setContext (app, context) {
|
|||||||
}
|
}
|
||||||
if (process.server) {
|
if (process.server) {
|
||||||
app.context.beforeNuxtRender = fn => context.beforeRenderFns.push(fn)
|
app.context.beforeNuxtRender = fn => context.beforeRenderFns.push(fn)
|
||||||
|
app.context.beforeSerialize = fn => context.beforeSerializeFns.push(fn)
|
||||||
}
|
}
|
||||||
if (process.client) {
|
if (process.client) {
|
||||||
app.context.nuxtState = window.<%= globals.context %>
|
app.context.nuxtState = window.<%= globals.context %>
|
||||||
|
@ -201,10 +201,16 @@ describe('basic ssr', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/special-state -> check window.__NUXT__.test = true', async () => {
|
test('/before-nuxt-render -> check window.__NUXT__.beforeNuxtRender = true', async () => {
|
||||||
const window = await nuxt.server.renderAndGetWindow(url('/special-state'))
|
const window = await nuxt.server.renderAndGetWindow(url('/before-nuxt-render'))
|
||||||
expect(window.document.title).toBe('Nuxt')
|
expect(window.document.title).toBe('Nuxt')
|
||||||
expect(window.__NUXT__.test).toBe(true)
|
expect(window.__NUXT__.beforeNuxtRender).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('/before-serialize -> check window.__NUXT__.beforeSerialize = true', async () => {
|
||||||
|
const window = await nuxt.server.renderAndGetWindow(url('/before-serialize'))
|
||||||
|
expect(window.document.title).toBe('Nuxt')
|
||||||
|
expect(window.__NUXT__.beforeSerialize).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/error', async () => {
|
test('/error', async () => {
|
||||||
|
@ -7,7 +7,7 @@ export default {
|
|||||||
middleware ({ beforeNuxtRender }) {
|
middleware ({ beforeNuxtRender }) {
|
||||||
if (process.server) {
|
if (process.server) {
|
||||||
beforeNuxtRender(({ nuxtState }) => {
|
beforeNuxtRender(({ nuxtState }) => {
|
||||||
nuxtState.test = true
|
nuxtState.beforeNuxtRender = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
26
test/fixtures/basic/pages/before-serialize.vue
vendored
Normal file
26
test/fixtures/basic/pages/before-serialize.vue
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Special state in `window.__NUXT__`</h1>
|
||||||
|
<client-only><pre>{{ nuxtState }}</pre></client-only>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
nuxtState: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fetch () {
|
||||||
|
if (process.server) {
|
||||||
|
this.$root.context.beforeSerialize((nuxtState) => {
|
||||||
|
nuxtState.beforeSerialize = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeMount () {
|
||||||
|
this.nuxtState = window.__NUXT__
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user