mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +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) {
|
||||
promise = promisify(Component.options.asyncData, app.context)
|
||||
} else {
|
||||
try {
|
||||
const payload = await this.fetchPayload(to.path).then((payloadData) => payloadData.data[i])
|
||||
promise = Promise.resolve(payload)
|
||||
} catch (err) {
|
||||
// fallback
|
||||
promise = promisify(Component.options.asyncData, app.context)
|
||||
}
|
||||
promise = this.fetchPayload(to.path)
|
||||
.then(payload => payload.data[i])
|
||||
.catch(_err => promisify(Component.options.asyncData, app.context)) // Fallback
|
||||
}
|
||||
<% } else { %>
|
||||
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
|
||||
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
|
||||
promises.push(this.fetchPayload(to.path).catch(err => null))
|
||||
}
|
||||
<% } %>
|
||||
<% } %>
|
||||
// Call fetch(context)
|
||||
if (hasFetch) {
|
||||
let p = Component.options.fetch(app.context)
|
||||
|
@ -100,6 +100,10 @@ export default async (ssrContext) => {
|
||||
ssrContext.rendered = () => {
|
||||
// Add the state from the vuex store
|
||||
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) { %>
|
||||
/*
|
||||
** Set layout
|
||||
|
@ -163,7 +163,7 @@ export default class SSRRenderer extends BaseRenderer {
|
||||
const preloadScripts = []
|
||||
renderContext.staticAssets = []
|
||||
const { staticAssetsBase, url, nuxt, staticAssets } = renderContext
|
||||
const { data, fetch, ...state } = nuxt
|
||||
const { data, fetch, mutations, ...state } = nuxt
|
||||
|
||||
// Initial state
|
||||
const nuxtStaticScript = `window.__NUXT_STATIC__='${staticAssetsBase}';`
|
||||
@ -186,7 +186,7 @@ export default class SSRRenderer extends BaseRenderer {
|
||||
const payloadPath = urlJoin(url, 'payload.js')
|
||||
const payloadUrl = urlJoin(staticAssetsBase, payloadPath)
|
||||
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 })
|
||||
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