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

prefetch

parent 6a421412
......@@ -11,7 +11,9 @@
"build:server": "NODE_ENV=production webpack --config webpack.server.config.js --progress --hide-modules"
},
"dependencies": {
"es6-promise": "^3.2.1",
"express": "^4.14.0",
"lru-cache": "^4.0.1",
"serialize-javascript": "^1.3.0",
"serve-favicon": "^2.3.0",
"vue": "^2.0.0-beta.6",
......
......@@ -2,7 +2,8 @@
<div id="app">
<img src="./assets/logo.png">
<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>
<li><router-link to="/">News</router-link></li>
<li><router-link to="/about">About</router-link></li>
......
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import router from './router'
import { sync } from 'vuex-router-sync'
sync(store, router)
const app = new Vue({
router,
......
require('es6-promise').polyfill()
import { app } from './app'
app.$mount('#app')
......@@ -9,7 +9,8 @@ import About from '../views/About.vue'
export default new Router({
mode: 'history',
routes: [
{ path: '/', component: News },
{ path: '/about', component: About }
{ path: '/news/:page', component: News },
{ path: '/about', component: About },
{ path: '*', redirect: '/news/1' }
]
})
......@@ -4,7 +4,14 @@ export default context => {
// set router's initial location
router.setInitialLocation(context.url)
// 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
return app
})
......
export function fetchItems (ids) {
return new Promise(resolve => {
resolve([{ id: 1, title: 'foo' }, { id: 2, title: 'bar' }])
})
}
import Vue from 'vue'
import Vuex from 'vuex'
import { fetchItems } from './api'
Vue.use(Vuex)
......@@ -8,19 +9,29 @@ const serverState = typeof window !== 'undefined' && window.__INITIAL_STATE__
// default state
const defaultState = {
url: '/'
storiesPerPage: 30,
topStoryIds: [],
items: {}
}
export default new Vuex.Store({
state: serverState || defaultState,
mutations: {
setURL: (state, url) => state.url = url
RECEIVE_ITEMS: (state, { items }) => {
for (const id in items) {
Vue.set(state.items, id, items[id])
}
}
},
actions: {
// just simulating an async action here
setURL: ({ commit }, url) => new Promise(resolve => {
commit('setURL', url)
setTimeout(resolve, 0)
FETCH_NEWS_BY_PAGE: ({ commit, state }, { page }) => {
const { storiesPerPage, topStoryIds } = state
const start = (page - 1) * storiesPerPage
const end = page * storiesPerPage
const ids = topStoryIds.slice(start, end)
return fetchItems(ids).then(items => {
commit('RECEIVE_ITEMS', { items })
})
}
}
})
......@@ -7,6 +7,10 @@
<script>
export default {
name: 'news'
name: 'news',
prefetch (store) {
const page = store.state.route.params.page
return store.dispatch('FETCH_NEWS_BY_PAGE', page)
}
}
</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