Loading component done

- Loading component working and customisable via nuxt.config.js (see
examples/async-data/)
- Accept callback for new Nuxt(options, cb) with cb(null, nuxt)
- Simplify async-data example
This commit is contained in:
Sébastien Chopin 2016-11-07 19:21:32 +01:00
parent 3d206de7a5
commit 2956e73c3e
7 changed files with 115 additions and 35 deletions

View File

@ -1,3 +1,8 @@
module.exports = {
vendor: ['axios'] // Add axios in the vendor.bundle.js
vendor: ['axios'], // Add axios in the vendor.bundle.js
loading: {
color: '#4FC08D',
failedColor: '#bf5050',
duration: 1500
}
}

View File

@ -11,13 +11,9 @@ const axios = require('axios')
export default {
data ({ req }) {
return new Promise((resolve, reject) => {
axios.get('https://jsonplaceholder.typicode.com/posts/1')
.then((res) => {
resolve({
post: res.data
})
})
return axios.get('https://jsonplaceholder.typicode.com/posts/1')
.then((res) => {
return { post: res.data }
})
}
}

View File

@ -26,15 +26,15 @@ export default {
err = err || null
this.err = err || null
<% if (loading) { %>
if (this.err && this.$loading) {
this.$loading.fail && this.$loading.fail()
if (this.err && this.$loading && this.$loading.fail) {
this.$loading.fail()
}
<% } %>
return this.err
}
},
components: {
ErrorPage
ErrorPage<%= (loading ? ',\n\t\tLoading' : '') %>
}
}
</script>

View File

@ -80,7 +80,7 @@ function render (to, from, next) {
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
next()
})
.catch(function (error) {
.catch((error) => {
this.error(error)
next(false)
})

View File

@ -1,31 +1,104 @@
<template>
<p>LOADING...</p>
<div class="progress" :style="{
'width': percent+'%',
'height': height,
'background-color': canSuccess? color : failedColor,
'opacity': show ? 1 : 0
}"></div>
</template>
<script>
const Vue = require('vue')
export default {
data () {
return {
percent: 0,
show: false,
canSuccess: true,
duration: <%= loading.duration %>,
loadingColor: '<%= loading.loadingColor %>',
errorColor: '<%= loading.errorColor %>',
height: '<%= loading.height %>',
color: '<%= loading.color %>',
failedColor: '<%= loading.failedColor %>',
}
},
methods: {
start () {},
increase () {},
decrease () {},
set () {},
finish () {},
pause () {},
hide () {},
fail () {}
start () {
this.show = true
this.canSuccess = true
if (this._timer) {
clearInterval(this._timer)
this.percent = 0
}
this._cut = 10000 / Math.floor(this.duration)
this._timer = setInterval(() => {
this.increase(this._cut * Math.random())
if (this.percent > 95) {
this.finish()
}
}, 100)
return this
},
set (num) {
this.show = true
this.canSuccess = true
this.percent = Math.floor(num)
return this
},
get () {
return Math.floor(this.percent)
},
increase (num) {
this.percent = this.percent + Math.floor(num)
return this
},
decrease () {
this.percent = this.percent - Math.floor(num)
return this
},
finish () {
this.percent = 100
this.hide()
return this
},
pause () {
clearInterval(this._timer)
return this
},
hide () {
clearInterval(this._timer)
this._timer = null
setTimeout(() => {
this.show = false
Vue.nextTick(() => {
setTimeout(() => {
this.percent = 0
}, 100)
})
}, 800)
return this
},
fail () {
this.canSuccess = false
this.percent = 100
this.hide()
return this
}
}
}
</script>
<style scoped>
p {
color: grey;
}
.progress {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
height: 2px;
width: 0%;
transition: width 0.2s, opacity 0.6s;
opacity: 1;
background-color: #efc14e;
z-index: 999999;
}
</style>

View File

@ -28,8 +28,9 @@ class Nuxt {
store: false,
cache: false,
loading: {
loadingColor: 'black',
errorColor: 'red',
color: 'black',
failedColor: 'red',
height: '2px',
duration: 5000
}
}
@ -55,12 +56,14 @@ class Nuxt {
this.build = build.bind(this)
// Launch build and set this.renderer
return co(this.build)
// .then((nuxt) => {
// if (typeof cb === 'function') cb(null, nuxt)
// })
// .catch((err) => {
// if (typeof cb === 'function') cb(err)
// })
.then((nuxt) => {
if (typeof cb === 'function') cb(null, nuxt)
return nuxt
})
.catch((err) => {
if (typeof cb === 'function') cb(err)
return err
})
}
render (req, res) {
@ -114,6 +117,9 @@ class Nuxt {
const self = this
return co(function * () {
const html = yield self.renderToString(context)
if (context.nuxt && context.nuxt.error instanceof Error) {
context.nuxt.error = { statusCode: 500, message: context.nuxt.error.message }
}
const app = self.appTemplate({
isProd: self.isProd, // Use to add the extracted CSS <link> in production
APP: html,

View File

@ -1,6 +1,6 @@
{
"name": "nuxt",
"version": "0.1.3",
"version": "0.1.4",
"description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)",
"main": "index.js",
"license": "MIT",