Commit 384d74e3 authored by Evan You's avatar Evan You

prefetch

parent 6a421412
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
"build:server": "NODE_ENV=production webpack --config webpack.server.config.js --progress --hide-modules" "build:server": "NODE_ENV=production webpack --config webpack.server.config.js --progress --hide-modules"
}, },
"dependencies": { "dependencies": {
"es6-promise": "^3.2.1",
"express": "^4.14.0", "express": "^4.14.0",
"lru-cache": "^4.0.1",
"serialize-javascript": "^1.3.0", "serialize-javascript": "^1.3.0",
"serve-favicon": "^2.3.0", "serve-favicon": "^2.3.0",
"vue": "^2.0.0-beta.6", "vue": "^2.0.0-beta.6",
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
<div id="app"> <div id="app">
<img src="./assets/logo.png"> <img src="./assets/logo.png">
<h1>{{ msg }}</h1> <h1>{{ msg }}</h1>
<p>Current URL is: {{ $store.state.url }} (from the store)</p> <p>Store state:</p>
<pre>{{ JSON.stringify($store.state, null, 2) }}</pre>
<ul> <ul>
<li><router-link to="/">News</router-link></li> <li><router-link to="/">News</router-link></li>
<li><router-link to="/about">About</router-link></li> <li><router-link to="/about">About</router-link></li>
......
import Vue from 'vue' import Vue from 'vue'
import App from './App.vue' import App from './App.vue'
import router from './router'
import store from './store' import store from './store'
import router from './router'
import { sync } from 'vuex-router-sync'
sync(store, router)
const app = new Vue({ const app = new Vue({
router, router,
......
require('es6-promise').polyfill()
import { app } from './app' import { app } from './app'
app.$mount('#app') app.$mount('#app')
...@@ -9,7 +9,8 @@ import About from '../views/About.vue' ...@@ -9,7 +9,8 @@ import About from '../views/About.vue'
export default new Router({ export default new Router({
mode: 'history', mode: 'history',
routes: [ routes: [
{ path: '/', component: News }, { path: '/news/:page', component: News },
{ path: '/about', component: About } { path: '/about', component: About },
{ path: '*', redirect: '/news/1' }
] ]
}) })
...@@ -4,7 +4,14 @@ export default context => { ...@@ -4,7 +4,14 @@ export default context => {
// set router's initial location // set router's initial location
router.setInitialLocation(context.url) router.setInitialLocation(context.url)
// resolve store state // resolve store state
return store.dispatch('setURL', context.url).then(() => { return Promise.all(router.history.current.matched.map(m => {
return Promise.all(Object.keys(m.components).map(key => {
const component = m.components[key]
if (component.prefetch) {
return component.prefetch(store)
}
}))
})).then(() => {
context.initialState = store.state context.initialState = store.state
return app return app
}) })
......
export function fetchItems (ids) {
return new Promise(resolve => {
resolve([{ id: 1, title: 'foo' }, { id: 2, title: 'bar' }])
})
}
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import { fetchItems } from './api'
Vue.use(Vuex) Vue.use(Vuex)
...@@ -8,19 +9,29 @@ const serverState = typeof window !== 'undefined' && window.__INITIAL_STATE__ ...@@ -8,19 +9,29 @@ const serverState = typeof window !== 'undefined' && window.__INITIAL_STATE__
// default state // default state
const defaultState = { const defaultState = {
url: '/' storiesPerPage: 30,
topStoryIds: [],
items: {}
} }
export default new Vuex.Store({ export default new Vuex.Store({
state: serverState || defaultState, state: serverState || defaultState,
mutations: { mutations: {
setURL: (state, url) => state.url = url RECEIVE_ITEMS: (state, { items }) => {
for (const id in items) {
Vue.set(state.items, id, items[id])
}
}
}, },
actions: { actions: {
// just simulating an async action here FETCH_NEWS_BY_PAGE: ({ commit, state }, { page }) => {
setURL: ({ commit }, url) => new Promise(resolve => { const { storiesPerPage, topStoryIds } = state
commit('setURL', url) const start = (page - 1) * storiesPerPage
setTimeout(resolve, 0) const end = page * storiesPerPage
const ids = topStoryIds.slice(start, end)
return fetchItems(ids).then(items => {
commit('RECEIVE_ITEMS', { items })
}) })
} }
}
}) })
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
<script> <script>
export default { export default {
name: 'news' name: 'news',
prefetch (store) {
const page = store.state.route.params.page
return store.dispatch('FETCH_NEWS_BY_PAGE', page)
}
} }
</script> </script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment