mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-30 15:22:39 +00:00
Layout with code-splitting!
This commit is contained in:
parent
afd7eb86e6
commit
3a0fcdee73
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<h1>Custom error page</h1>
|
||||
<div class="container">
|
||||
<h1>Sorry, page not found</h1>
|
||||
<nuxt-link to="/">Home page</nuxt-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -7,3 +10,14 @@ export default {
|
||||
props: ['error']
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
font-family: sans-serif;
|
||||
padding-top: 10%;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 4.2 KiB |
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<nuxt-container>
|
||||
<component :is="layout"></component>
|
||||
<component v-if="layout" :is="layout"></component>
|
||||
</nuxt-container>
|
||||
</template>
|
||||
|
||||
@ -9,19 +9,37 @@ let layouts = {
|
||||
<%
|
||||
var layoutsKeys = Object.keys(layouts);
|
||||
layoutsKeys.forEach(function (key, i) { %>
|
||||
_<%= key %>: require('<%= layouts[key] %>')<%= (i + 1) < layoutsKeys.length ? ',' : '' %>
|
||||
_<%= key %>: process.BROWSER_BUILD ? () => System.import('<%= layouts[key] %>') : require('<%= layouts[key] %>')<%= (i + 1) < layoutsKeys.length ? ',' : '' %>
|
||||
<% }) %>
|
||||
}
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return { layout: layouts._default }
|
||||
return { layout: null }
|
||||
},
|
||||
methods: {
|
||||
setLayout (layout) {
|
||||
if (!layout || !layouts['_' + layout]) layout = 'default'
|
||||
this.layout = layouts['_' + layout]
|
||||
return layout
|
||||
let _layout = '_' + layout
|
||||
if (typeof layouts[_layout] === 'function') {
|
||||
return this.loadLayout(_layout)
|
||||
}
|
||||
this.layout = layouts[_layout]
|
||||
return Promise.resolve(this.layout)
|
||||
},
|
||||
loadLayout (_layout) {
|
||||
return layouts[_layout]()
|
||||
.then((Component) => {
|
||||
layouts[_layout] = Component
|
||||
this.layout = layouts[_layout]
|
||||
return this.layout
|
||||
})
|
||||
.catch((e) => {
|
||||
if (this.$nuxt) {
|
||||
return this.$nuxt.error({ statusCode: 500, message: e.message })
|
||||
}
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,13 @@ function loadAsyncComponents (to, ___, next) {
|
||||
function render (to, from, next) {
|
||||
let Components = getMatchedComponents(to)
|
||||
if (!Components.length) {
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
|
||||
return next()
|
||||
// Default layout
|
||||
this.setLayout()
|
||||
.then(() => {
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
|
||||
return next()
|
||||
})
|
||||
return
|
||||
}
|
||||
// Update ._data and other properties if hot reloaded
|
||||
Components.forEach(function (Component) {
|
||||
@ -79,57 +84,61 @@ function render (to, from, next) {
|
||||
}
|
||||
}
|
||||
})
|
||||
this.setLayout(Components[0].options.layout)
|
||||
this.setTransitions(mapTransitions(Components, to, from))
|
||||
this.error()
|
||||
let nextCalled = false
|
||||
let isValid = true
|
||||
Components.forEach((Component) => {
|
||||
if (!isValid) return
|
||||
if (typeof Component.options.validate !== 'function') return
|
||||
isValid = Component.options.validate({
|
||||
params: to.params || {},
|
||||
query: to.query || {}
|
||||
})
|
||||
})
|
||||
if (!isValid) {
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
|
||||
return next()
|
||||
}
|
||||
Promise.all(Components.map((Component, i) => {
|
||||
// Check if only children route changed
|
||||
Component._path = compile(to.matched[i].path)(to.params)
|
||||
if (Component._path === _lastPaths[i] && (i + 1) !== Components.length) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
let promises = []
|
||||
const _next = function (path) {
|
||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||
nextCalled = true
|
||||
next(path)
|
||||
}
|
||||
const context = getContext({ to<%= (store ? ', store' : '') %>, isClient: true, next: _next.bind(this), error: this.error.bind(this) })
|
||||
// Validate method
|
||||
if (Component._data && typeof Component._data === 'function') {
|
||||
var promise = promisify(Component._data, context)
|
||||
promise.then((data) => {
|
||||
Component.options.data = () => data || {}
|
||||
Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
|
||||
if (Component._Ctor && Component._Ctor.options) {
|
||||
Component._Ctor.options.data = Component.options.data
|
||||
}
|
||||
<%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
|
||||
// Set layout
|
||||
this.setLayout(Components[0].options.layout)
|
||||
.then(() => {
|
||||
// Pass validation?
|
||||
let isValid = true
|
||||
Components.forEach((Component) => {
|
||||
if (!isValid) return
|
||||
if (typeof Component.options.validate !== 'function') return
|
||||
isValid = Component.options.validate({
|
||||
params: to.params || {},
|
||||
query: to.query || {}
|
||||
})
|
||||
promises.push(promise)
|
||||
})
|
||||
if (!isValid) {
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
|
||||
return next()
|
||||
}
|
||||
if (Component.options.fetch) {
|
||||
var p = Component.options.fetch(context)
|
||||
if (!(p instanceof Promise)) { p = Promise.resolve(p) }
|
||||
<%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
|
||||
promises.push(p)
|
||||
}
|
||||
return Promise.all(promises)
|
||||
}))
|
||||
return Promise.all(Components.map((Component, i) => {
|
||||
// Check if only children route changed
|
||||
Component._path = compile(to.matched[i].path)(to.params)
|
||||
if (Component._path === _lastPaths[i] && (i + 1) !== Components.length) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
let promises = []
|
||||
const _next = function (path) {
|
||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||
nextCalled = true
|
||||
next(path)
|
||||
}
|
||||
const context = getContext({ to<%= (store ? ', store' : '') %>, isClient: true, next: _next.bind(this), error: this.error.bind(this) })
|
||||
// Validate method
|
||||
if (Component._data && typeof Component._data === 'function') {
|
||||
var promise = promisify(Component._data, context)
|
||||
promise.then((data) => {
|
||||
Component.options.data = () => data || {}
|
||||
Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
|
||||
if (Component._Ctor && Component._Ctor.options) {
|
||||
Component._Ctor.options.data = Component.options.data
|
||||
}
|
||||
<%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
|
||||
})
|
||||
promises.push(promise)
|
||||
}
|
||||
if (Component.options.fetch) {
|
||||
var p = Component.options.fetch(context)
|
||||
if (!(p instanceof Promise)) { p = Promise.resolve(p) }
|
||||
<%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
|
||||
promises.push(p)
|
||||
}
|
||||
return Promise.all(promises)
|
||||
}))
|
||||
})
|
||||
.then(() => {
|
||||
_lastPaths = Components.map((Component, i) => compile(to.matched[i].path)(to.params))
|
||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||
@ -175,8 +184,8 @@ function hotReloadAPI (_app) {
|
||||
Component = Vue.extend(Component)
|
||||
Component._Ctor = Component
|
||||
}
|
||||
_app.setLayout(Component.options.layout)
|
||||
let promises = []
|
||||
promises.push(_app.setLayout(Component.options.layout))
|
||||
const next = function (path) {
|
||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||
router.push(path)
|
||||
@ -268,6 +277,13 @@ function nuxtReady (app) {
|
||||
Promise.all(resolveComponents)
|
||||
.then((Components) => {
|
||||
const _app = new Vue(app)
|
||||
|
||||
return _app.setLayout(Components.length ? Components[0].options.layout : '')
|
||||
.then(() => {
|
||||
return { _app, Components }
|
||||
})
|
||||
})
|
||||
.then(({ _app, Components }) => {
|
||||
const mountApp = () => {
|
||||
_app.$mount('#__nuxt')
|
||||
<% if (loading) { %>
|
||||
@ -285,9 +301,6 @@ Promise.all(resolveComponents)
|
||||
store.replaceState(NUXT.state)
|
||||
}
|
||||
<% } %>
|
||||
if (Components.length) {
|
||||
_app.setLayout(Components[0].options.layout)
|
||||
}
|
||||
_app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app)
|
||||
if (Components.length) {
|
||||
_app.setTransitions(mapTransitions(Components, router.currentRoute))
|
||||
|
@ -74,9 +74,9 @@ export default context => {
|
||||
return Component
|
||||
})
|
||||
// Set layout
|
||||
if (Components.length && Components[0].options.layout) {
|
||||
_app.setLayout(Components[0].options.layout)
|
||||
}
|
||||
return _app.setLayout(Components.length ? Components[0].options.layout : '')
|
||||
})
|
||||
.then(() => {
|
||||
// Call .validate()
|
||||
let isValid = true
|
||||
Components.forEach((Component) => {
|
||||
|
Loading…
Reference in New Issue
Block a user