mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-19 23:21:09 +00:00
feat: store and replay vuex mutations for static target (#7350)
* feat: store and replay vuex mutations for static target * test: add full-static fixture * perf: clean store subscription before render * fix: record mutations after nuxtServerInit and middleware
This commit is contained in:
parent
498f408d9a
commit
42406d6075
@ -491,13 +491,9 @@ async function render (to, from, next) {
|
|||||||
if (this.isPreview) {
|
if (this.isPreview) {
|
||||||
promise = promisify(Component.options.asyncData, app.context)
|
promise = promisify(Component.options.asyncData, app.context)
|
||||||
} else {
|
} else {
|
||||||
try {
|
promise = this.fetchPayload(to.path)
|
||||||
const payload = await this.fetchPayload(to.path).then((payloadData) => payloadData.data[i])
|
.then(payload => payload.data[i])
|
||||||
promise = Promise.resolve(payload)
|
.catch(_err => promisify(Component.options.asyncData, app.context)) // Fallback
|
||||||
} catch (err) {
|
|
||||||
// fallback
|
|
||||||
promise = promisify(Component.options.asyncData, app.context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
const promise = promisify(Component.options.asyncData, app.context)
|
const promise = promisify(Component.options.asyncData, app.context)
|
||||||
@ -514,6 +510,13 @@ async function render (to, from, next) {
|
|||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
<% if (isFullStatic && store) { %>
|
||||||
|
// Replay store mutations
|
||||||
|
promises.push(this.fetchPayload(to.path).then(payload => {
|
||||||
|
payload.mutations.forEach(m => { this.$store.commit(m[0], m[1]) })
|
||||||
|
}))
|
||||||
|
<% } %>
|
||||||
|
|
||||||
// Check disabled page loading
|
// Check disabled page loading
|
||||||
this.$loading.manual = Component.options.loading === false
|
this.$loading.manual = Component.options.loading === false
|
||||||
|
|
||||||
@ -523,7 +526,7 @@ async function render (to, from, next) {
|
|||||||
// Catching the error here for letting the SPA fallback and normal fetch behaviour
|
// Catching the error here for letting the SPA fallback and normal fetch behaviour
|
||||||
promises.push(this.fetchPayload(to.path).catch(err => null))
|
promises.push(this.fetchPayload(to.path).catch(err => null))
|
||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
// Call fetch(context)
|
// Call fetch(context)
|
||||||
if (hasFetch) {
|
if (hasFetch) {
|
||||||
let p = Component.options.fetch(app.context)
|
let p = Component.options.fetch(app.context)
|
||||||
|
@ -100,6 +100,10 @@ export default async (ssrContext) => {
|
|||||||
ssrContext.rendered = () => {
|
ssrContext.rendered = () => {
|
||||||
// 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) { %>
|
||||||
|
// Stop recording store mutations
|
||||||
|
ssrContext.unsetMutationObserver()
|
||||||
|
<% } %>
|
||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
}
|
}
|
||||||
@ -175,6 +179,12 @@ export default async (ssrContext) => {
|
|||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
<% if (isFullStatic && store) { %>
|
||||||
|
// Record store mutations for full-static after nuxtServerInit and Middleware
|
||||||
|
ssrContext.nuxt.mutations =[]
|
||||||
|
ssrContext.unsetMutationObserver = store.subscribe(m => { ssrContext.nuxt.mutations.push([m.type, m.payload]) })
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<% if (features.layouts) { %>
|
<% if (features.layouts) { %>
|
||||||
/*
|
/*
|
||||||
** Set layout
|
** Set layout
|
||||||
|
@ -163,7 +163,7 @@ export default class SSRRenderer extends BaseRenderer {
|
|||||||
const preloadScripts = []
|
const preloadScripts = []
|
||||||
renderContext.staticAssets = []
|
renderContext.staticAssets = []
|
||||||
const { staticAssetsBase, url, nuxt, staticAssets } = renderContext
|
const { staticAssetsBase, url, nuxt, staticAssets } = renderContext
|
||||||
const { data, fetch, ...state } = nuxt
|
const { data, fetch, mutations, ...state } = nuxt
|
||||||
|
|
||||||
// Initial state
|
// Initial state
|
||||||
const nuxtStaticScript = `window.__NUXT_STATIC__='${staticAssetsBase}';`
|
const nuxtStaticScript = `window.__NUXT_STATIC__='${staticAssetsBase}';`
|
||||||
@ -186,7 +186,7 @@ export default class SSRRenderer extends BaseRenderer {
|
|||||||
const payloadPath = urlJoin(url, 'payload.js')
|
const payloadPath = urlJoin(url, 'payload.js')
|
||||||
const payloadUrl = urlJoin(staticAssetsBase, payloadPath)
|
const payloadUrl = urlJoin(staticAssetsBase, payloadPath)
|
||||||
const routePath = (url.replace(/\/+$/, '') || '/').split('?')[0] // remove trailing slah and query params
|
const routePath = (url.replace(/\/+$/, '') || '/').split('?')[0] // remove trailing slah and query params
|
||||||
const payloadScript = `__NUXT_JSONP__("${routePath}", ${devalue({ data, fetch })});`
|
const payloadScript = `__NUXT_JSONP__("${routePath}", ${devalue({ data, fetch, mutations })});`
|
||||||
staticAssets.push({ path: payloadPath, src: payloadScript })
|
staticAssets.push({ path: payloadPath, src: payloadScript })
|
||||||
preloadScripts.push(payloadUrl)
|
preloadScripts.push(payloadUrl)
|
||||||
|
|
||||||
|
3
test/fixtures/full-static/full-static.test.js
vendored
Normal file
3
test/fixtures/full-static/full-static.test.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { buildFixture } from '../../utils/build'
|
||||||
|
|
||||||
|
buildFixture('full-static')
|
21
test/fixtures/full-static/layouts/default.vue
vendored
Normal file
21
test/fixtures/full-static/layouts/default.vue
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<NLink to="/">
|
||||||
|
Home
|
||||||
|
</NLink>
|
||||||
|
<NLink to="/store">
|
||||||
|
Store
|
||||||
|
</NLink>
|
||||||
|
<NLink to="/pagination/1">
|
||||||
|
Pagination
|
||||||
|
</NLink>
|
||||||
|
<br>
|
||||||
|
<Nuxt />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
a {
|
||||||
|
margin: 0 1em;
|
||||||
|
}
|
||||||
|
</style>
|
3
test/fixtures/full-static/nuxt.config.js
vendored
Normal file
3
test/fixtures/full-static/nuxt.config.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
target: 'static'
|
||||||
|
}
|
5
test/fixtures/full-static/pages/index.vue
vendored
Normal file
5
test/fixtures/full-static/pages/index.vue
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Full Static Playground!</h1>
|
||||||
|
</div>
|
||||||
|
</template>
|
21
test/fixtures/full-static/pages/pagination/_i.vue
vendored
Normal file
21
test/fixtures/full-static/pages/pagination/_i.vue
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<NLink v-if="i>0" :to="`./${i-1}`">
|
||||||
|
Previous
|
||||||
|
</NLink>
|
||||||
|
Page {{ i }}
|
||||||
|
<NLink v-if="i<5" :to="`./${i+1}`">
|
||||||
|
Next
|
||||||
|
</NLink>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
i () {
|
||||||
|
return parseInt(this.$route.params.i) || 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
18
test/fixtures/full-static/pages/store.vue
vendored
Normal file
18
test/fixtures/full-static/pages/store.vue
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>Welcome {{ $store.state.auth.user.name }}!</h3>
|
||||||
|
<br>
|
||||||
|
You visited this page <strong>{{ $store.state.counter }}</strong> times.
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
fetch () {
|
||||||
|
this.$store.commit('COUNT')
|
||||||
|
},
|
||||||
|
async asyncData ({ store }) {
|
||||||
|
await store.dispatch('auth/FETCH_USER')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
17
test/fixtures/full-static/store/auth.js
vendored
Normal file
17
test/fixtures/full-static/store/auth.js
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export const state = () => ({
|
||||||
|
user: null
|
||||||
|
})
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
SET_USER (state, user) {
|
||||||
|
state.user = user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
FETCH_USER ({ commit }) {
|
||||||
|
commit('SET_USER', {
|
||||||
|
name: (process.client ? 'C' : 'S') + ' Æ A-' + (10 + Math.round(Math.random() * 10))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
9
test/fixtures/full-static/store/index.js
vendored
Normal file
9
test/fixtures/full-static/store/index.js
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export const state = () => ({
|
||||||
|
counter: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
COUNT (state) {
|
||||||
|
state.counter += 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user