mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 23:52:06 +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
|
||||
next: NextFunction
|
||||
beforeRenderFns: Array<() => any>
|
||||
beforeSerializeFns: Array<() => any>
|
||||
fetchCounters: Record<string, number>
|
||||
nuxt: {
|
||||
layout: string
|
||||
@ -87,6 +88,7 @@ export interface Context {
|
||||
error(params: NuxtError): void
|
||||
nuxtState: NuxtState
|
||||
beforeNuxtRender(fn: (params: { Components: VueRouter['getMatchedComponents'], nuxtState: NuxtState }) => void): void
|
||||
beforeSerialize(fn: (nuxtState: NuxtState) => void): void
|
||||
enablePreview?: (previewData?: Record<string, any>) => void
|
||||
$preview?: Record<string, any>
|
||||
}
|
||||
|
@ -183,6 +183,7 @@ async function createApp(ssrContext, config = {}) {
|
||||
req: ssrContext ? ssrContext.req : undefined,
|
||||
res: ssrContext ? ssrContext.res : undefined,
|
||||
beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined,
|
||||
beforeSerializeFns: ssrContext ? ssrContext.beforeSerializeFns : undefined,
|
||||
ssrContext
|
||||
})
|
||||
|
||||
|
@ -85,6 +85,8 @@ export default async (ssrContext) => {
|
||||
ssrContext.next = createNext(ssrContext)
|
||||
// Used for beforeNuxtRender({ Components, nuxtState })
|
||||
ssrContext.beforeRenderFns = []
|
||||
// for beforeSerialize(nuxtState)
|
||||
ssrContext.beforeSerializeFns = []
|
||||
// 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: '' }
|
||||
<% if (features.fetch) { %>
|
||||
@ -120,16 +122,21 @@ export default async (ssrContext) => {
|
||||
const beforeRender = async () => {
|
||||
// Call beforeNuxtRender() methods
|
||||
await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt })))
|
||||
<% if (store) { %>
|
||||
|
||||
ssrContext.rendered = () => {
|
||||
// Call beforeSerialize() hooks
|
||||
ssrContext.beforeSerializeFns.forEach(fn => fn(ssrContext.nuxt))
|
||||
|
||||
<% if (store) { %>
|
||||
// Add the state from the vuex store
|
||||
ssrContext.nuxt.state = store.state
|
||||
<% } %>
|
||||
|
||||
<% if (isFullStatic && store) { %>
|
||||
// Stop recording store mutations
|
||||
ssrContext.unsetMutationObserver()
|
||||
<% } %>
|
||||
}
|
||||
<% } %>
|
||||
}
|
||||
|
||||
const renderErrorPage = async () => {
|
||||
|
@ -259,6 +259,7 @@ export async function setContext (app, context) {
|
||||
}
|
||||
if (process.server) {
|
||||
app.context.beforeNuxtRender = fn => context.beforeRenderFns.push(fn)
|
||||
app.context.beforeSerialize = fn => context.beforeSerializeFns.push(fn)
|
||||
}
|
||||
if (process.client) {
|
||||
app.context.nuxtState = window.<%= globals.context %>
|
||||
|
@ -201,10 +201,16 @@ describe('basic ssr', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('/special-state -> check window.__NUXT__.test = true', async () => {
|
||||
const window = await nuxt.server.renderAndGetWindow(url('/special-state'))
|
||||
test('/before-nuxt-render -> check window.__NUXT__.beforeNuxtRender = true', async () => {
|
||||
const window = await nuxt.server.renderAndGetWindow(url('/before-nuxt-render'))
|
||||
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 () => {
|
||||
|
@ -7,7 +7,7 @@ export default {
|
||||
middleware ({ beforeNuxtRender }) {
|
||||
if (process.server) {
|
||||
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