Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
node-sample
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
周韬
node-sample
Commits
413d30ab
Commit
413d30ab
authored
Apr 22, 2017
by
Evan You
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use progress bar instead of spinner for route transitions
parent
e86305b7
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
127 additions
and
21 deletions
+127
-21
App.vue
src/App.vue
+0
-2
Item.vue
src/components/Item.vue
+1
-1
ProgressBar.vue
src/components/ProgressBar.vue
+102
-0
entry-client.js
src/entry-client.js
+22
-6
ItemList.vue
src/views/ItemList.vue
+2
-6
UserView.vue
src/views/UserView.vue
+0
-6
No files found.
src/App.vue
View file @
413d30ab
...
...
@@ -92,8 +92,6 @@ a
padding 15px 30px
@media (max-width 600px)
body
font-size 14px
.header
.inner
padding 15px
...
...
src/components/Item.vue
View file @
413d30ab
...
...
@@ -3,7 +3,7 @@
<span
class=
"score"
>
{{
item
.
score
}}
</span>
<span
class=
"title"
>
<template
v-if=
"item.url"
>
<a
:href=
"item.url"
target=
"_blank"
>
{{
item
.
title
}}
</a>
<a
:href=
"item.url"
target=
"_blank"
rel=
"noopener"
>
{{
item
.
title
}}
</a>
<span
class=
"host"
>
(
{{
item
.
url
|
host
}}
)
</span>
</
template
>
<
template
v-else
>
...
...
src/components/ProgressBar.vue
0 → 100644
View file @
413d30ab
<!-- borrowed from Nuxt! -->
<
template
>
<div
class=
"progress"
:style=
"
{
'width': percent+'%',
'height': height,
'background-color': canSuccess? color : failedColor,
'opacity': show ? 1 : 0
}">
</div>
</
template
>
<
script
>
export
default
{
data
()
{
return
{
percent
:
0
,
show
:
false
,
canSuccess
:
true
,
duration
:
3000
,
height
:
'2px'
,
color
:
'#ffca2b'
,
failedColor
:
'#ff0000'
,
}
},
methods
:
{
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
(
num
)
{
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
this
.
$nextTick
(()
=>
{
setTimeout
(()
=>
{
this
.
percent
=
0
},
200
)
})
},
500
)
return
this
},
fail
()
{
this
.
canSuccess
=
false
return
this
}
}
}
</
script
>
<
style
scoped
>
.progress
{
position
:
fixed
;
top
:
0px
;
left
:
0px
;
right
:
0px
;
height
:
2px
;
width
:
0%
;
transition
:
width
0.2s
,
opacity
0.4s
;
opacity
:
1
;
background-color
:
#efc14e
;
z-index
:
999999
;
}
</
style
>
src/entry-client.js
View file @
413d30ab
import
Vue
from
'vue'
import
'es6-promise/auto'
import
{
createApp
}
from
'./app'
import
ProgressBar
from
'./components/ProgressBar.vue'
// global progress bar
const
bar
=
Vue
.
prototype
.
$bar
=
new
Vue
(
ProgressBar
).
$mount
()
document
.
body
.
appendChild
(
bar
.
$el
)
// a global mixin that calls `asyncData` when a route component's params change
Vue
.
mixin
({
...
...
@@ -10,7 +15,7 @@ Vue.mixin({
asyncData
({
store
:
this
.
$store
,
route
:
to
}).
then
(
next
)
}).
then
(
next
)
.
catch
(
next
)
}
else
{
next
()
}
...
...
@@ -28,15 +33,26 @@ if (window.__INITIAL_STATE__) {
// wait until router has resolved all async before hooks
// and async components...
router
.
onReady
(()
=>
{
// add router hook for handling asyncData
// doing it after initial route is resolved so that we don't double-fetch
// the data that we already have.
// Add router hook for handling asyncData.
// Doing it after initial route is resolved so that we don't double-fetch
// the data that we already have. Using router.beforeResolve() so that all
// async components are resolved.
router
.
beforeResolve
((
to
,
from
,
next
)
=>
{
Promise
.
all
(
router
.
getMatchedComponents
(
to
).
map
(
c
=>
{
const
matched
=
router
.
getMatchedComponents
(
to
)
const
prevMatched
=
router
.
getMatchedComponents
(
from
)
const
activated
=
matched
.
filter
(
c
=>
prevMatched
.
indexOf
(
c
)
<
0
)
if
(
!
activated
.
length
)
{
return
next
()
}
bar
.
start
()
Promise
.
all
(
activated
.
map
(
c
=>
{
if
(
c
.
asyncData
)
{
return
c
.
asyncData
({
store
,
route
:
to
})
}
})).
then
(
next
)
})).
then
(()
=>
{
bar
.
finish
()
next
()
}).
catch
(
next
)
})
// actually mount to DOM
...
...
src/views/ItemList.vue
View file @
413d30ab
<
template
>
<div
class=
"news-view"
>
<spinner
:show=
"loading"
></spinner>
<div
class=
"news-list-nav"
>
<router-link
v-if=
"page > 1"
:to=
"'/' + type + '/' + (page - 1)"
>
<
prev
</router-link>
<a
v-else
class=
"disabled"
>
<
prev
</a>
...
...
@@ -22,13 +21,11 @@
<
script
>
import
{
watchList
}
from
'../api'
import
Item
from
'../components/Item.vue'
import
Spinner
from
'../components/Spinner.vue'
export
default
{
name
:
'item-list'
,
components
:
{
Spinner
,
Item
},
...
...
@@ -39,7 +36,6 @@ export default {
data
()
{
const
isInitialRender
=
!
this
.
$root
.
_isMounted
return
{
loading
:
false
,
transition
:
'slide-up'
,
displayedPage
:
isInitialRender
?
Number
(
this
.
$store
.
state
.
route
.
params
.
page
)
||
1
:
-
1
,
displayedItems
:
isInitialRender
?
this
.
$store
.
getters
.
activeItems
:
[]
...
...
@@ -84,7 +80,7 @@ export default {
methods
:
{
loadItems
(
to
=
this
.
page
,
from
=
-
1
)
{
this
.
loading
=
true
this
.
$bar
.
start
()
this
.
$store
.
dispatch
(
'FETCH_LIST_DATA'
,
{
type
:
this
.
type
}).
then
(()
=>
{
...
...
@@ -97,7 +93,7 @@ export default {
:
to
>
from
?
'slide-left'
:
'slide-right'
this
.
displayedPage
=
to
this
.
displayedItems
=
this
.
$store
.
getters
.
activeItems
this
.
loading
=
false
this
.
$bar
.
finish
()
})
}
}
...
...
src/views/UserView.vue
View file @
413d30ab
<
template
>
<div
class=
"user-view"
>
<spinner
:show=
"!userLoaded"
></spinner>
<template
v-if=
"user"
>
<h1>
User :
{{
user
.
id
}}
</h1>
<ul
class=
"meta"
>
...
...
@@ -21,18 +20,13 @@
<
script
>
import
{
setTitle
}
from
'../util/title'
import
Spinner
from
'../components/Spinner.vue'
export
default
{
name
:
'user-view'
,
components
:
{
Spinner
},
computed
:
{
user
()
{
return
this
.
$store
.
state
.
users
[
this
.
$route
.
params
.
id
]
},
userLoaded
()
{
return
this
.
$route
.
params
.
id
in
this
.
$store
.
state
.
users
}
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment