mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 08:02:01 +00:00
Remove dynamic components
This commit is contained in:
parent
f07d9855b6
commit
2cc78c0446
@ -160,11 +160,9 @@ async function render (to, from, next) {
|
|||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
let promises = []
|
let promises = []
|
||||||
// Create this context for asyncData & fetch (used for dynamic component injection)
|
|
||||||
const _this = { components: {} }
|
|
||||||
// asyncData method
|
// asyncData method
|
||||||
if (Component.options.asyncData && typeof Component.options.asyncData === 'function') {
|
if (Component.options.asyncData && typeof Component.options.asyncData === 'function') {
|
||||||
var promise = promisify(Component.options.asyncData.bind(_this), context)
|
var promise = promisify(Component.options.asyncData, context)
|
||||||
promise.then((asyncDataResult) => {
|
promise.then((asyncDataResult) => {
|
||||||
applyAsyncData(Component, asyncDataResult)
|
applyAsyncData(Component, asyncDataResult)
|
||||||
<%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
|
<%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
|
||||||
@ -172,19 +170,12 @@ async function render (to, from, next) {
|
|||||||
promises.push(promise)
|
promises.push(promise)
|
||||||
}
|
}
|
||||||
if (Component.options.fetch) {
|
if (Component.options.fetch) {
|
||||||
var p = Component.options.fetch.call(_this, context)
|
var p = Component.options.fetch(context)
|
||||||
if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) { p = Promise.resolve(p) }
|
if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) { p = Promise.resolve(p) }
|
||||||
<%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
|
<%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
|
||||||
promises.push(p)
|
promises.push(p)
|
||||||
}
|
}
|
||||||
return Promise.all(promises)
|
return Promise.all(promises)
|
||||||
.then(() => {
|
|
||||||
Object.keys(_this.components).forEach((name) => {
|
|
||||||
// Sanetize resolved components (Temporary workaround for vue-loader 13.0.0)
|
|
||||||
_this.components[name] = _this.components[name].default || _this.components[name]
|
|
||||||
Component.options.components[name] = _this.components[name]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
_lastPaths = Components.map((Component, i) => compile(to.matched[i].path)(to.params))
|
_lastPaths = Components.map((Component, i) => compile(to.matched[i].path)(to.params))
|
||||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||||
|
@ -56,11 +56,7 @@ export default async context => {
|
|||||||
|
|
||||||
// Add route to the context
|
// Add route to the context
|
||||||
context.route = router.currentRoute
|
context.route = router.currentRoute
|
||||||
|
|
||||||
// Components array (for dynamic components)
|
|
||||||
context.hasDynamicComponents = false
|
|
||||||
context.components = []
|
|
||||||
|
|
||||||
// Nuxt object
|
// Nuxt object
|
||||||
context.nuxt = { layout: 'default', data: [], error: null<%= (store ? ', state: null' : '') %>, serverRendered: true }
|
context.nuxt = { layout: 'default', data: [], error: null<%= (store ? ', state: null' : '') %>, serverRendered: true }
|
||||||
|
|
||||||
@ -171,12 +167,9 @@ export default async context => {
|
|||||||
let asyncDatas = await Promise.all(Components.map(Component => {
|
let asyncDatas = await Promise.all(Components.map(Component => {
|
||||||
let promises = []
|
let promises = []
|
||||||
|
|
||||||
// Create this context for asyncData & fetch (used for dynamic component injection)
|
|
||||||
const _this = { components: {} }
|
|
||||||
|
|
||||||
// Call asyncData(context)
|
// Call asyncData(context)
|
||||||
if (Component.options.asyncData && typeof Component.options.asyncData === 'function') {
|
if (Component.options.asyncData && typeof Component.options.asyncData === 'function') {
|
||||||
let promise = promisify(Component.options.asyncData.bind(_this), ctx)
|
let promise = promisify(Component.options.asyncData, ctx)
|
||||||
promise.then(asyncDataResult => {
|
promise.then(asyncDataResult => {
|
||||||
context.asyncData[Component.options.name] = asyncDataResult
|
context.asyncData[Component.options.name] = asyncDataResult
|
||||||
applyAsyncData(Component)
|
applyAsyncData(Component)
|
||||||
@ -189,39 +182,13 @@ export default async context => {
|
|||||||
|
|
||||||
// Call fetch(context)
|
// Call fetch(context)
|
||||||
if (Component.options.fetch) {
|
if (Component.options.fetch) {
|
||||||
promises.push(Component.options.fetch.call(_this, ctx))
|
promises.push(Component.options.fetch(ctx))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
promises.push(null)
|
promises.push(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then(data => {
|
return Promise.all(promises)
|
||||||
// If no dynamic component, return data directly
|
|
||||||
if (Object.keys(_this.components).length === 0) {
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sanetize resolved components (Temporary workaround for vue-loader 13.0.0)
|
|
||||||
Object.keys(_this.components).forEach(name => {
|
|
||||||
_this.components[name] = _this.components[name].default || _this.components[name]
|
|
||||||
})
|
|
||||||
|
|
||||||
// Tell renderer that dynamic components has been added
|
|
||||||
context.hasDynamicComponents = true
|
|
||||||
|
|
||||||
// Add Component on server side (clone of it)
|
|
||||||
Component.options.components = {
|
|
||||||
...Component.options.components,
|
|
||||||
...clone(_this.components) // Clone it to avoid vue to overwrite references
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add components into __NUXT__ for client-side hydration
|
|
||||||
// We clone it since vue-server-renderer will update the component definition
|
|
||||||
context.components.push(sanitizeDynamicComponents(_this.components))
|
|
||||||
|
|
||||||
// Return data to server-render them
|
|
||||||
return data
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// If no Components found, returns 404
|
// If no Components found, returns 404
|
||||||
@ -257,23 +224,3 @@ export default async context => {
|
|||||||
|
|
||||||
return _app
|
return _app
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitizeDynamicComponents(components) {
|
|
||||||
Object.keys(components).forEach((name) => {
|
|
||||||
const component = components[name]
|
|
||||||
// Remove SSR register hookd
|
|
||||||
if (Array.isArray(component.beforeCreate)) {
|
|
||||||
component.beforeCreate = component.beforeCreate.filter((fn) => fn !== component._ssrRegister)
|
|
||||||
if (!component.beforeCreate.length) delete component.beforeCreate
|
|
||||||
}
|
|
||||||
// Remove SSR & informations properties
|
|
||||||
delete component._ssrRegister
|
|
||||||
delete component.__file
|
|
||||||
if (component.staticRenderFns && !component.staticRenderFns.length) {
|
|
||||||
delete component.staticRenderFns
|
|
||||||
}
|
|
||||||
// Add Component to NUXT.components[i][name]
|
|
||||||
components[name] = component
|
|
||||||
})
|
|
||||||
return clone(components)
|
|
||||||
}
|
|
||||||
|
@ -345,12 +345,7 @@ export default class Renderer extends Tapable {
|
|||||||
HEAD += resourceHints
|
HEAD += resourceHints
|
||||||
}
|
}
|
||||||
HEAD += context.renderStyles()
|
HEAD += context.renderStyles()
|
||||||
APP += `<script type="text/javascript">`
|
APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })};</script>`
|
||||||
APP += `window.__NUXT__=${serialize(context.nuxt, { isJSON: true })};`
|
|
||||||
if (context.hasDynamicComponents) {
|
|
||||||
APP += `window.__COMPONENTS__=${serialize(context.components)};`
|
|
||||||
}
|
|
||||||
APP += `</script>`
|
|
||||||
APP += context.renderScripts()
|
APP += context.renderScripts()
|
||||||
|
|
||||||
let html = this.resources.appTemplate({
|
let html = this.resources.appTemplate({
|
||||||
|
9
test/fixtures/ssr/pages/asyncComponent.vue
vendored
9
test/fixtures/ssr/pages/asyncComponent.vue
vendored
@ -5,14 +5,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const AsyncTest = () => import('@/components/test.vue').then((m) => m.default || m)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async asyncData({ error }) {
|
components:{
|
||||||
try {
|
AsyncTest
|
||||||
this.components.AsyncTest = await import(`@/components/test.vue`)
|
|
||||||
} catch (e) {
|
|
||||||
error({ statusCode: 404, message: 'Can not load test component' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -62,9 +62,10 @@ test('unique responses with component', async t => {
|
|||||||
await uniqueTest(t, '/component')
|
await uniqueTest(t, '/component')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('unique responses with async components', async t => {
|
test.todo('unique responses with async components (wait Vue 2.4)')
|
||||||
await uniqueTest(t, '/asyncComponent')
|
// test('unique responses with async components', async t => {
|
||||||
})
|
// await uniqueTest(t, '/asyncComponent')
|
||||||
|
// })
|
||||||
|
|
||||||
test('unique responses with asyncData()', async t => {
|
test('unique responses with asyncData()', async t => {
|
||||||
await uniqueTest(t, '/asyncData')
|
await uniqueTest(t, '/asyncData')
|
||||||
|
Loading…
Reference in New Issue
Block a user