Add loading: false option to pages (#3629)

* Add hasManualLoading

* Add hasManualLoading (2)

* Debugging

* Debugging (2)

* Change 'manual' to false

* Add custom-page-loading example

* Add custom-page-loading example (2)

* Changed approach

* Added custom-page-loading/README.md

* Change running loading time in about.vue

* Patch loadAsyncComponents

* Added final page

* Changed approach (2)

* Fixed example

* Fixed example (2)

* Fix example package name

* Linting

* Improved examples (more to the point)

* Linting (2)

* Fix typo

* Adjust indentation

* Added noloading.vue to basic fixture

* Added noloading tests

* Linting (3)

* Debugging test

* Linting (4)

* Debugging test (2)

* Debugging test (3)
This commit is contained in:
Jonas Galvez 2018-08-05 18:56:49 -03:00 committed by Sébastien Chopin
parent dbba872be2
commit 0e42e98751
8 changed files with 159 additions and 5 deletions

View File

@ -0,0 +1,5 @@
# Custom page loading with Nuxt.js
https://nuxtjs.org/examples/custom-page-loading
Use `loading: false` in page to manually call $loading.finish() and $loading.start() methods.

View File

@ -0,0 +1,11 @@
{
"name": "example-custom-page-loading",
"dependencies": {
"nuxt": "latest"
},
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start"
}
}

View File

@ -0,0 +1,49 @@
<template>
<div class="container">
<p>About Page</p>
<p>It should take 5 seconds for the loader to disappear</p>
<p>It should take 5 seconds for the route to change after you
<span class="link" @click="goToFinal">click here</span></p>
</div>
</template>
<script>
export default {
loading: false,
asyncData() {
return new Promise((resolve) => {
setTimeout(function () {
resolve({})
}, 1000)
})
},
mounted() {
setTimeout(() => {
// Extend loader for an additional 5s
this.$nuxt.$loading.finish()
}, 5000)
},
methods: {
goToFinal() {
// Start loader immediately
this.$nuxt.$loading.start()
// Actually change route 5s later
setTimeout(() => {
this.$router.push('/final')
}, 5000)
}
}
}
</script>
<style scoped>
.link {
cursor: pointer;
text-decoration: underline;
}
.container {
font-size: 20px;
text-align: center;
padding-top: 100px;
}
</style>

View File

@ -0,0 +1,19 @@
<template>
<div class="container">
<p>Final Page</p>
<nuxt-link to="/">Go to /</nuxt-link>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.container {
font-size: 20px;
text-align: center;
padding-top: 100px;
}
</style>

View File

@ -0,0 +1,26 @@
<template>
<div class="container">
<p>Hello {{ name }}!</p>
<nuxt-link to="/about">Go to /about</nuxt-link>
</div>
</template>
<script>
export default {
asyncData() {
return new Promise((resolve) => {
setTimeout(function () {
resolve({ name: 'world' })
}, 1000)
})
}
}
</script>
<style scoped>
.container {
font-size: 20px;
text-align: center;
padding-top: 100px;
}
</style>

View File

@ -115,7 +115,7 @@ async function loadAsyncComponents (to, from, next) {
this._diffQuery = (this._queryChanged ? getQueryDiff(to.query, from.query) : []) this._diffQuery = (this._queryChanged ? getQueryDiff(to.query, from.query) : [])
<% if (loading) { %> <% if (loading) { %>
if (this._pathChanged && this.$loading.start) { if (this._pathChanged && this.$loading.start && !this.$loading.manual) {
this.$loading.start() this.$loading.start()
} }
<% } %> <% } %>
@ -133,7 +133,7 @@ async function loadAsyncComponents (to, from, next) {
} }
return false return false
}) })
if (startLoader && this.$loading.start) { if (startLoader && this.$loading.start && !this.$loading.manual) {
this.$loading.start() this.$loading.start()
} }
} }
@ -316,7 +316,7 @@ async function render (to, from, next) {
const hasAsyncData = Component.options.asyncData && typeof Component.options.asyncData === 'function' const hasAsyncData = Component.options.asyncData && typeof Component.options.asyncData === 'function'
const hasFetch = !!Component.options.fetch const hasFetch = !!Component.options.fetch
<% if(loading) { %>const loadingIncrease = (hasAsyncData && hasFetch) ? 30 : 45<% } %> <% if (loading) { %>const loadingIncrease = (hasAsyncData && hasFetch) ? 30 : 45<% } %>
// Call asyncData(context) // Call asyncData(context)
if (hasAsyncData) { if (hasAsyncData) {
@ -328,6 +328,9 @@ async function render (to, from, next) {
promises.push(promise) promises.push(promise)
} }
// Check disabled page loading
this.$loading.manual = Component.options.loading === false
// Call fetch(context) // Call fetch(context)
if (hasFetch) { if (hasFetch) {
let p = Component.options.fetch(app.context) let p = Component.options.fetch(app.context)
@ -345,7 +348,10 @@ async function render (to, from, next) {
// If not redirected // If not redirected
if (!nextCalled) { if (!nextCalled) {
<% if (loading) { %>if(this.$loading.finish) this.$loading.finish()<% } %>
<% if (loading) { %>
if (this.$loading.finish && !this.$loading.manual) this.$loading.finish()
<% } %>
next() next()
} }
@ -489,7 +495,9 @@ function addHotReload ($component, depth) {
next: next.bind(this) next: next.bind(this)
}) })
const context = app.context const context = app.context
<%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %> <% if (loading) { %>
if (this.$loading.start && !this.$loading.manual) this.$loading.start()
<% } %>
callMiddleware.call(this, Components, context) callMiddleware.call(this, Components, context)
.then(() => { .then(() => {
// If layout changed // If layout changed

View File

@ -27,6 +27,20 @@ describe('basic browser', () => {
expect(await page.$text('h1')).toBe('Index page') expect(await page.$text('h1')).toBe('Index page')
}) })
test('/noloading', async () => {
const { hook } = await page.nuxt.navigate('/noloading', true)
let loading = await page.nuxt.loadingData()
expect(loading.show).toBe(true)
await hook
expect(loading.show).toBe(true)
await new Promise((resolve) => {
setTimeout(() => resolve(), 1800)
})
loading = await page.nuxt.loadingData()
expect(loading.percent).toBe(100)
})
test('/stateless', async () => { test('/stateless', async () => {
const { hook } = await page.nuxt.navigate('/stateless', false) const { hook } = await page.nuxt.navigate('/stateless', false)
const loading = await page.nuxt.loadingData() const loading = await page.nuxt.loadingData()

22
test/fixtures/basic/pages/noloading.vue vendored Normal file
View File

@ -0,0 +1,22 @@
<template>
<p>{{ name }}</p>
</template>
<script>
export default {
loading: false,
asyncData() {
return new Promise((resolve) => {
setTimeout(() => resolve({ name: 'Nuxt.js' }), 10)
})
},
watch: {
$route(to) {
this.$nuxt.$loading.start()
}
},
mounted() {
setTimeout(() => this.$nuxt.$loading.finish(), 1500)
}
}
</script>