mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-06 21:10:38 +00:00
Add layout feature
This commit is contained in:
parent
6b9af524aa
commit
b870a7206e
@ -1,5 +1,28 @@
|
||||
<template>
|
||||
<nuxt-container>
|
||||
<nuxt/>
|
||||
<component :is="layout"></component>
|
||||
</nuxt-container>
|
||||
</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) {
|
||||
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
|
||||
const originalDataFn = Component._data.toString().replace(/\s/g, '')
|
||||
const dataFn = Component._dataFn
|
||||
const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
|
||||
// If component data method changed
|
||||
if (newDataFn !== originalDataFn && newDataFn !== dataFn) {
|
||||
Component._data = Component._Ctor.options.data || noopData
|
||||
if (Component._dataFn) {
|
||||
const originalDataFn = Component._data.toString().replace(/\s/g, '')
|
||||
const dataFn = Component._dataFn
|
||||
const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
|
||||
// If component data method changed
|
||||
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.error()
|
||||
let nextCalled = false
|
||||
@ -172,6 +175,7 @@ function hotReloadAPI (_app) {
|
||||
Component = Vue.extend(Component)
|
||||
Component._Ctor = Component
|
||||
}
|
||||
_app.setLayout(Component.options.layout)
|
||||
let promises = []
|
||||
const next = function (path) {
|
||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||
@ -281,6 +285,9 @@ 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))
|
||||
|
@ -22,6 +22,8 @@ export default {
|
||||
Vue.prototype.$nuxt = this
|
||||
// Add this.$root.$nuxt
|
||||
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
|
||||
if (typeof window !== 'undefined') {
|
||||
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
|
||||
})
|
||||
// Set layout
|
||||
if (Components.length && Components[0].options.layout) {
|
||||
_app.setLayout(Components[0].options.layout)
|
||||
}
|
||||
// Call .validate()
|
||||
let isValid = true
|
||||
Components.forEach((Component) => {
|
||||
|
@ -132,6 +132,14 @@ function * buildFiles () {
|
||||
|
||||
function * generateRoutesAndFiles () {
|
||||
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
|
||||
const files = yield glob('pages/**/*.vue', { cwd: this.srcDir })
|
||||
this.routes = _.uniq(_.map(files, (file) => {
|
||||
@ -165,6 +173,7 @@ function * generateRoutesAndFiles () {
|
||||
css: this.options.css,
|
||||
plugins: this.options.plugins.map((p) => r(this.srcDir, p)),
|
||||
appPath: './App.vue',
|
||||
layouts: layouts,
|
||||
loading: (typeof this.options.loading === 'string' ? r(this.srcDir, this.options.loading) : this.options.loading),
|
||||
transition: this.options.transition,
|
||||
components: {
|
||||
@ -174,12 +183,15 @@ function * generateRoutesAndFiles () {
|
||||
}
|
||||
// Format routes for the lib/app/router.js template
|
||||
templateVars.router.routes = createRoutes(files, this.srcDir)
|
||||
if (fs.existsSync(join(this.srcDir, 'layouts', 'app.vue'))) {
|
||||
templateVars.appPath = r(this.srcDir, 'layouts/app.vue')
|
||||
}
|
||||
if (fs.existsSync(join(this.srcDir, 'layouts', 'error.vue'))) {
|
||||
if (layoutsFiles.includes('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) => {
|
||||
return readFile(r(__dirname, 'app', file), 'utf8')
|
||||
.then((fileContent) => {
|
||||
|
Loading…
Reference in New Issue
Block a user