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
530a486c
Commit
530a486c
authored
Apr 11, 2017
by
Evan You
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
restructure
parent
6482f808
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
139 additions
and
128 deletions
+139
-128
app.js
src/app.js
+23
-15
entry-client.js
src/entry-client.js
+3
-1
entry-server.js
src/entry-server.js
+3
-1
index.js
src/router/index.js
+7
-18
actions.js
src/store/actions.js
+49
-0
getters.js
src/store/getters.js
+21
-0
index.js
src/store/index.js
+9
-92
mutations.js
src/store/mutations.js
+23
-0
CreateListView.js
src/views/CreateListView.js
+1
-1
No files found.
src/app.js
View file @
530a486c
import
Vue
from
'vue'
import
Vue
from
'vue'
import
App
from
'./App.vue'
import
App
from
'./App.vue'
import
store
from
'./store'
import
{
createStore
}
from
'./store'
import
router
from
'./router'
import
{
createRouter
}
from
'./router'
import
{
sync
}
from
'vuex-router-sync'
import
{
sync
}
from
'vuex-router-sync'
import
*
as
filters
from
'./filters'
import
*
as
filters
from
'./filters'
// sync the router with the vuex store.
// this registers `store.state.route`
sync
(
store
,
router
)
// register global utility filters.
// register global utility filters.
Object
.
keys
(
filters
).
forEach
(
key
=>
{
Object
.
keys
(
filters
).
forEach
(
key
=>
{
Vue
.
filter
(
key
,
filters
[
key
])
Vue
.
filter
(
key
,
filters
[
key
])
})
})
// create the app instance.
// Expose a factory function that creates a fresh set of store, router,
// here we inject the router and store to all child components,
// app instances on each call (which is called for each SSR request)
// making them available everywhere as `this.$router` and `this.$store`.
export
function
createApp
()
{
const
app
=
new
Vue
({
// create store and router instances
const
store
=
createStore
()
const
router
=
createRouter
()
// sync the router with the vuex store.
// this registers `store.state.route`
sync
(
store
,
router
)
// create the app instance.
// here we inject the router and store to all child components,
// making them available everywhere as `this.$router` and `this.$store`.
const
app
=
new
Vue
({
router
,
router
,
store
,
store
,
render
:
h
=>
h
(
App
)
render
:
h
=>
h
(
App
)
})
})
// expose the app, the router and the store.
// expose the app, the router and the store.
// note we are not mounting the app here, since bootstrapping will be
// note we are not mounting the app here, since bootstrapping will be
// different depending on whether we are in a browser or on the server.
// different depending on whether we are in a browser or on the server.
export
{
app
,
router
,
store
}
return
{
app
,
router
,
store
}
}
src/entry-client.js
View file @
530a486c
import
'es6-promise/auto'
import
'es6-promise/auto'
import
{
app
,
store
,
router
}
from
'./app'
import
{
createApp
}
from
'./app'
const
{
app
,
router
,
store
}
=
createApp
()
// prime the store with server-initialized state.
// prime the store with server-initialized state.
// the state is determined during SSR and inlined in the page markup.
// the state is determined during SSR and inlined in the page markup.
...
...
src/entry-server.js
View file @
530a486c
import
{
app
,
router
,
store
}
from
'./app'
import
{
createApp
}
from
'./app'
const
isDev
=
process
.
env
.
NODE_ENV
!==
'production'
const
isDev
=
process
.
env
.
NODE_ENV
!==
'production'
...
@@ -10,6 +10,8 @@ const isDev = process.env.NODE_ENV !== 'production'
...
@@ -10,6 +10,8 @@ const isDev = process.env.NODE_ENV !== 'production'
export
default
context
=>
{
export
default
context
=>
{
const
s
=
isDev
&&
Date
.
now
()
const
s
=
isDev
&&
Date
.
now
()
const
{
app
,
router
,
store
}
=
createApp
()
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
// set router's location
// set router's location
router
.
push
(
context
.
url
)
router
.
push
(
context
.
url
)
...
...
src/router/index.js
View file @
530a486c
...
@@ -3,24 +3,12 @@ import Router from 'vue-router'
...
@@ -3,24 +3,12 @@ import Router from 'vue-router'
Vue
.
use
(
Router
)
Vue
.
use
(
Router
)
// We are using Webpack code splitting here so that each route's associated
import
createListView
from
'../views/CreateListView'
// component code is loaded on-demand only when the route is visited.
import
ItemView
from
'../views/ItemView.vue'
// It's actually not really necessary for a small project of this size but
import
UserView
from
'../views/UserView.vue'
// the goal is to demonstrate how to do it.
//
// Note that the dynamic import syntax should actually be just `import()`
// but buble/acorn doesn't support parsing that syntax until it's stage 4
// so we use the old System.import here instead.
//
// If using Babel, `import()` can be supported via
// babel-plugin-syntax-dynamic-import.
const
createListView
=
name
=>
()
=>
export
function
createRouter
()
{
System
.
import
(
'../views/CreateListView'
).
then
(
m
=>
m
.
createListView
(
name
))
return
new
Router
({
const
ItemView
=
()
=>
System
.
import
(
'../views/ItemView.vue'
)
const
UserView
=
()
=>
System
.
import
(
'../views/UserView.vue'
)
export
default
new
Router
({
mode
:
'history'
,
mode
:
'history'
,
scrollBehavior
:
()
=>
({
y
:
0
}),
scrollBehavior
:
()
=>
({
y
:
0
}),
routes
:
[
routes
:
[
...
@@ -33,4 +21,5 @@ export default new Router({
...
@@ -33,4 +21,5 @@ export default new Router({
{
path
:
'/user/:id'
,
component
:
UserView
},
{
path
:
'/user/:id'
,
component
:
UserView
},
{
path
:
'/'
,
redirect
:
'/top'
}
{
path
:
'/'
,
redirect
:
'/top'
}
]
]
})
})
}
src/store/actions.js
0 → 100644
View file @
530a486c
import
{
fetchUser
,
fetchItems
,
fetchIdsByType
}
from
'./api'
export
default
{
// ensure data for rendering given list type
FETCH_LIST_DATA
:
({
commit
,
dispatch
,
state
},
{
type
})
=>
{
commit
(
'SET_ACTIVE_TYPE'
,
{
type
})
return
fetchIdsByType
(
type
)
.
then
(
ids
=>
commit
(
'SET_LIST'
,
{
type
,
ids
}))
.
then
(()
=>
dispatch
(
'ENSURE_ACTIVE_ITEMS'
))
},
// ensure all active items are fetched
ENSURE_ACTIVE_ITEMS
:
({
dispatch
,
getters
})
=>
{
return
dispatch
(
'FETCH_ITEMS'
,
{
ids
:
getters
.
activeIds
})
},
FETCH_ITEMS
:
({
commit
,
state
},
{
ids
})
=>
{
// on the client, the store itself serves as a cache.
// only fetch items that we do not already have, or has expired (3 minutes)
const
now
=
Date
.
now
()
ids
=
ids
.
filter
(
id
=>
{
const
item
=
state
.
items
[
id
]
if
(
!
item
)
{
return
true
}
if
(
now
-
item
.
__lastUpdated
>
1000
*
60
*
3
)
{
return
true
}
return
false
})
if
(
ids
.
length
)
{
return
fetchItems
(
ids
).
then
(
items
=>
commit
(
'SET_ITEMS'
,
{
items
}))
}
else
{
return
Promise
.
resolve
()
}
},
FETCH_USER
:
({
commit
,
state
},
{
id
})
=>
{
return
state
.
users
[
id
]
?
Promise
.
resolve
(
state
.
users
[
id
])
:
fetchUser
(
id
).
then
(
user
=>
commit
(
'SET_USER'
,
{
user
}))
}
}
src/store/getters.js
0 → 100644
View file @
530a486c
export
default
{
// ids of the items that should be currently displayed based on
// current list type and current pagination
activeIds
(
state
)
{
const
{
activeType
,
itemsPerPage
,
lists
}
=
state
const
page
=
Number
(
state
.
route
.
params
.
page
)
||
1
if
(
activeType
)
{
const
start
=
(
page
-
1
)
*
itemsPerPage
const
end
=
page
*
itemsPerPage
return
lists
[
activeType
].
slice
(
start
,
end
)
}
else
{
return
[]
}
},
// items that should be currently displayed.
// this Array may not be fully fetched.
activeItems
(
state
,
getters
)
{
return
getters
.
activeIds
.
map
(
id
=>
state
.
items
[
id
]).
filter
(
_
=>
_
)
}
}
src/store/index.js
View file @
530a486c
import
Vue
from
'vue'
import
Vue
from
'vue'
import
Vuex
from
'vuex'
import
Vuex
from
'vuex'
import
{
fetchItems
,
fetchIdsByType
,
fetchUser
}
from
'./api'
import
actions
from
'./actions'
import
mutations
from
'./mutations'
import
getters
from
'./getters'
Vue
.
use
(
Vuex
)
Vue
.
use
(
Vuex
)
const
store
=
new
Vuex
.
Store
({
export
function
createStore
()
{
return
new
Vuex
.
Store
({
state
:
{
state
:
{
activeType
:
null
,
activeType
:
null
,
itemsPerPage
:
20
,
itemsPerPage
:
20
,
...
@@ -18,94 +21,8 @@ const store = new Vuex.Store({
...
@@ -18,94 +21,8 @@ const store = new Vuex.Store({
job
:
[]
job
:
[]
}
}
},
},
actions
,
actions
:
{
mutations
,
// ensure data for rendering given list type
getters
FETCH_LIST_DATA
:
({
commit
,
dispatch
,
state
},
{
type
})
=>
{
commit
(
'SET_ACTIVE_TYPE'
,
{
type
})
return
fetchIdsByType
(
type
)
.
then
(
ids
=>
commit
(
'SET_LIST'
,
{
type
,
ids
}))
.
then
(()
=>
dispatch
(
'ENSURE_ACTIVE_ITEMS'
))
},
// ensure all active items are fetched
ENSURE_ACTIVE_ITEMS
:
({
dispatch
,
getters
})
=>
{
return
dispatch
(
'FETCH_ITEMS'
,
{
ids
:
getters
.
activeIds
})
},
FETCH_ITEMS
:
({
commit
,
state
},
{
ids
})
=>
{
// on the client, the store itself serves as a cache.
// only fetch items that we do not already have, or has expired (3 minutes)
const
now
=
Date
.
now
()
ids
=
ids
.
filter
(
id
=>
{
const
item
=
state
.
items
[
id
]
if
(
!
item
)
{
return
true
}
if
(
now
-
item
.
__lastUpdated
>
1000
*
60
*
3
)
{
return
true
}
return
false
})
})
if
(
ids
.
length
)
{
}
return
fetchItems
(
ids
).
then
(
items
=>
commit
(
'SET_ITEMS'
,
{
items
}))
}
else
{
return
Promise
.
resolve
()
}
},
FETCH_USER
:
({
commit
,
state
},
{
id
})
=>
{
return
state
.
users
[
id
]
?
Promise
.
resolve
(
state
.
users
[
id
])
:
fetchUser
(
id
).
then
(
user
=>
commit
(
'SET_USER'
,
{
user
}))
}
},
mutations
:
{
SET_ACTIVE_TYPE
:
(
state
,
{
type
})
=>
{
state
.
activeType
=
type
},
SET_LIST
:
(
state
,
{
type
,
ids
})
=>
{
state
.
lists
[
type
]
=
ids
},
SET_ITEMS
:
(
state
,
{
items
})
=>
{
items
.
forEach
(
item
=>
{
if
(
item
)
{
Vue
.
set
(
state
.
items
,
item
.
id
,
item
)
}
})
},
SET_USER
:
(
state
,
{
user
})
=>
{
Vue
.
set
(
state
.
users
,
user
.
id
,
user
)
}
},
getters
:
{
// ids of the items that should be currently displayed based on
// current list type and current pagination
activeIds
(
state
)
{
const
{
activeType
,
itemsPerPage
,
lists
}
=
state
const
page
=
Number
(
state
.
route
.
params
.
page
)
||
1
if
(
activeType
)
{
const
start
=
(
page
-
1
)
*
itemsPerPage
const
end
=
page
*
itemsPerPage
return
lists
[
activeType
].
slice
(
start
,
end
)
}
else
{
return
[]
}
},
// items that should be currently displayed.
// this Array may not be fully fetched.
activeItems
(
state
,
getters
)
{
return
getters
.
activeIds
.
map
(
id
=>
state
.
items
[
id
]).
filter
(
_
=>
_
)
}
}
})
export
default
store
src/store/mutations.js
0 → 100644
View file @
530a486c
import
Vue
from
'vue'
export
default
{
SET_ACTIVE_TYPE
:
(
state
,
{
type
})
=>
{
state
.
activeType
=
type
},
SET_LIST
:
(
state
,
{
type
,
ids
})
=>
{
state
.
lists
[
type
]
=
ids
},
SET_ITEMS
:
(
state
,
{
items
})
=>
{
items
.
forEach
(
item
=>
{
if
(
item
)
{
Vue
.
set
(
state
.
items
,
item
.
id
,
item
)
}
})
},
SET_USER
:
(
state
,
{
user
})
=>
{
Vue
.
set
(
state
.
users
,
user
.
id
,
user
)
}
}
src/views/CreateListView.js
View file @
530a486c
...
@@ -3,7 +3,7 @@ import ItemList from '../components/ItemList.vue'
...
@@ -3,7 +3,7 @@ import ItemList from '../components/ItemList.vue'
// This is a factory function for dynamically creating root-level list views,
// This is a factory function for dynamically creating root-level list views,
// since they share most of the logic except for the type of items to display.
// since they share most of the logic except for the type of items to display.
// They are essentially higher order components wrapping ItemList.vue.
// They are essentially higher order components wrapping ItemList.vue.
export
function
createListView
(
type
)
{
export
default
function
createListView
(
type
)
{
return
{
return
{
name
:
`
${
type
}
-stories-view`
,
name
:
`
${
type
}
-stories-view`
,
// this will be called during SSR to pre-fetch data into the store!
// this will be called during SSR to pre-fetch data into the store!
...
...
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