mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-07 09:22:27 +00:00
Add layout feature
This commit is contained in:
parent
6b9af524aa
commit
b870a7206e
@ -1,5 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<nuxt-container>
|
<nuxt-container>
|
||||||
<nuxt/>
|
<component :is="layout"></component>
|
||||||
</nuxt-container>
|
</nuxt-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let layouts = {
|
||||||
|
<%
|
||||||
|
var layoutsKeys = Object.keys(layouts);
|
||||||
|
layoutsKeys.forEach(function (key, i) { %>
|
||||||
|
_<%= key %>: require('<%= layouts[key] %>')<%= (i + 1) < layoutsKeys.length ? ',' : '' %>
|
||||||
|
<% }) %>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return { layout: layouts._default }
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setLayout (layout) {
|
||||||
|
if (!layout || !layouts['_' + layout]) layout = 'default'
|
||||||
|
this.layout = layouts['_' + layout]
|
||||||
|
return layout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@ -66,17 +66,20 @@ function render (to, from, next) {
|
|||||||
if (!Component._data) {
|
if (!Component._data) {
|
||||||
Component._data = Component.options.data || noopData
|
Component._data = Component.options.data || noopData
|
||||||
}
|
}
|
||||||
if (Component._Ctor && Component._Ctor.options && Component._dataFn) {
|
if (Component._Ctor && Component._Ctor.options) {
|
||||||
Component.options.fetch = Component._Ctor.options.fetch
|
Component.options.fetch = Component._Ctor.options.fetch
|
||||||
const originalDataFn = Component._data.toString().replace(/\s/g, '')
|
if (Component._dataFn) {
|
||||||
const dataFn = Component._dataFn
|
const originalDataFn = Component._data.toString().replace(/\s/g, '')
|
||||||
const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
|
const dataFn = Component._dataFn
|
||||||
// If component data method changed
|
const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
|
||||||
if (newDataFn !== originalDataFn && newDataFn !== dataFn) {
|
// If component data method changed
|
||||||
Component._data = Component._Ctor.options.data || noopData
|
if (newDataFn !== originalDataFn && newDataFn !== dataFn) {
|
||||||
|
Component._data = Component._Ctor.options.data || noopData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
this.setLayout(Components[0].options.layout)
|
||||||
this.setTransitions(mapTransitions(Components, to, from))
|
this.setTransitions(mapTransitions(Components, to, from))
|
||||||
this.error()
|
this.error()
|
||||||
let nextCalled = false
|
let nextCalled = false
|
||||||
@ -172,6 +175,7 @@ function hotReloadAPI (_app) {
|
|||||||
Component = Vue.extend(Component)
|
Component = Vue.extend(Component)
|
||||||
Component._Ctor = Component
|
Component._Ctor = Component
|
||||||
}
|
}
|
||||||
|
_app.setLayout(Component.options.layout)
|
||||||
let promises = []
|
let promises = []
|
||||||
const next = function (path) {
|
const next = function (path) {
|
||||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||||
@ -281,6 +285,9 @@ Promise.all(resolveComponents)
|
|||||||
store.replaceState(NUXT.state)
|
store.replaceState(NUXT.state)
|
||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
|
if (Components.length) {
|
||||||
|
_app.setLayout(Components[0].options.layout)
|
||||||
|
}
|
||||||
_app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app)
|
_app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app)
|
||||||
if (Components.length) {
|
if (Components.length) {
|
||||||
_app.setTransitions(mapTransitions(Components, router.currentRoute))
|
_app.setTransitions(mapTransitions(Components, router.currentRoute))
|
||||||
|
@ -22,6 +22,8 @@ export default {
|
|||||||
Vue.prototype.$nuxt = this
|
Vue.prototype.$nuxt = this
|
||||||
// Add this.$root.$nuxt
|
// Add this.$root.$nuxt
|
||||||
this.$root.$nuxt = this
|
this.$root.$nuxt = this
|
||||||
|
// Bind $nuxt.setLayout(layout) to $root.setLayout
|
||||||
|
this.setLayout = this.$root.setLayout.bind(this.$root)
|
||||||
// add to window so we can listen when ready
|
// add to window so we can listen when ready
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.$nuxt = this
|
window.$nuxt = this
|
||||||
|
3
lib/app/layouts/default.vue
Normal file
3
lib/app/layouts/default.vue
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<nuxt/>
|
||||||
|
</template>
|
@ -73,6 +73,10 @@ export default context => {
|
|||||||
}
|
}
|
||||||
return Component
|
return Component
|
||||||
})
|
})
|
||||||
|
// Set layout
|
||||||
|
if (Components.length && Components[0].options.layout) {
|
||||||
|
_app.setLayout(Components[0].options.layout)
|
||||||
|
}
|
||||||
// Call .validate()
|
// Call .validate()
|
||||||
let isValid = true
|
let isValid = true
|
||||||
Components.forEach((Component) => {
|
Components.forEach((Component) => {
|
||||||
|
@ -132,6 +132,14 @@ function * buildFiles () {
|
|||||||
|
|
||||||
function * generateRoutesAndFiles () {
|
function * generateRoutesAndFiles () {
|
||||||
debug('Generating routes...')
|
debug('Generating routes...')
|
||||||
|
// Layouts
|
||||||
|
let layouts = {}
|
||||||
|
const layoutsFiles = yield glob('layouts/*.vue', { cwd: this.srcDir })
|
||||||
|
layoutsFiles.forEach((file) => {
|
||||||
|
let name = file.split('/').slice(-1)[0].replace('.vue', '')
|
||||||
|
if (name === 'error') return
|
||||||
|
layouts[name] = r(this.srcDir, file)
|
||||||
|
})
|
||||||
// Generate routes based on files
|
// Generate routes based on files
|
||||||
const files = yield glob('pages/**/*.vue', { cwd: this.srcDir })
|
const files = yield glob('pages/**/*.vue', { cwd: this.srcDir })
|
||||||
this.routes = _.uniq(_.map(files, (file) => {
|
this.routes = _.uniq(_.map(files, (file) => {
|
||||||
@ -165,6 +173,7 @@ function * generateRoutesAndFiles () {
|
|||||||
css: this.options.css,
|
css: this.options.css,
|
||||||
plugins: this.options.plugins.map((p) => r(this.srcDir, p)),
|
plugins: this.options.plugins.map((p) => r(this.srcDir, p)),
|
||||||
appPath: './App.vue',
|
appPath: './App.vue',
|
||||||
|
layouts: layouts,
|
||||||
loading: (typeof this.options.loading === 'string' ? r(this.srcDir, this.options.loading) : this.options.loading),
|
loading: (typeof this.options.loading === 'string' ? r(this.srcDir, this.options.loading) : this.options.loading),
|
||||||
transition: this.options.transition,
|
transition: this.options.transition,
|
||||||
components: {
|
components: {
|
||||||
@ -174,12 +183,15 @@ function * generateRoutesAndFiles () {
|
|||||||
}
|
}
|
||||||
// Format routes for the lib/app/router.js template
|
// Format routes for the lib/app/router.js template
|
||||||
templateVars.router.routes = createRoutes(files, this.srcDir)
|
templateVars.router.routes = createRoutes(files, this.srcDir)
|
||||||
if (fs.existsSync(join(this.srcDir, 'layouts', 'app.vue'))) {
|
if (layoutsFiles.includes('layouts/error.vue')) {
|
||||||
templateVars.appPath = r(this.srcDir, 'layouts/app.vue')
|
|
||||||
}
|
|
||||||
if (fs.existsSync(join(this.srcDir, 'layouts', 'error.vue'))) {
|
|
||||||
templateVars.components.ErrorPage = r(this.srcDir, 'layouts/error.vue')
|
templateVars.components.ErrorPage = r(this.srcDir, 'layouts/error.vue')
|
||||||
}
|
}
|
||||||
|
// If no default layout, create its folder and add the default folder
|
||||||
|
if (!layouts.default) {
|
||||||
|
yield mkdirp(r(this.dir, '.nuxt/layouts'))
|
||||||
|
templatesFiles.push('layouts/default.vue')
|
||||||
|
layouts.default = r(__dirname, 'app', 'layouts', 'default.vue')
|
||||||
|
}
|
||||||
let moveTemplates = templatesFiles.map((file) => {
|
let moveTemplates = templatesFiles.map((file) => {
|
||||||
return readFile(r(__dirname, 'app', file), 'utf8')
|
return readFile(r(__dirname, 'app', file), 'utf8')
|
||||||
.then((fileContent) => {
|
.then((fileContent) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user