Commit e7014499 authored by Evan You's avatar Evan You

add some comments

parent d7581f75
...@@ -7,6 +7,8 @@ const resolve = file => path.resolve(__dirname, file) ...@@ -7,6 +7,8 @@ const resolve = file => path.resolve(__dirname, file)
const express = require('express') const express = require('express')
const favicon = require('serve-favicon') const favicon = require('serve-favicon')
const serialize = require('serialize-javascript') const serialize = require('serialize-javascript')
// https://github.com/vuejs/vue/blob/next/packages/vue-server-renderer/README.md#why-use-bundlerenderer
const createBundleRenderer = require('vue-server-renderer').createBundleRenderer const createBundleRenderer = require('vue-server-renderer').createBundleRenderer
const app = express() const app = express()
......
...@@ -5,16 +5,25 @@ import router from './router' ...@@ -5,16 +5,25 @@ import router 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) sync(store, router)
// 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.
// 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({ const app = new Vue({
router, router,
store, store,
...App ...App // Object spread copying everything from App.vue
}) })
// expose the app, the router and the store.
// note we not mounting the app here, since bootstrapping will be
// different depending on whether we are in browser or on the server.
export { app, router, store } export { app, router, store }
require('es6-promise').polyfill() require('es6-promise').polyfill()
import { app, store } from './app' import { app, store } from './app'
// 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.
store.replaceState(window.__INITIAL_STATE__) store.replaceState(window.__INITIAL_STATE__)
// actually mount to DOM
app.$mount('#app') app.$mount('#app')
...@@ -2,19 +2,33 @@ import { app, router, store } from './app' ...@@ -2,19 +2,33 @@ import { app, router, store } from './app'
const isDev = process.env.NODE_ENV !== 'production' const isDev = process.env.NODE_ENV !== 'production'
// This exported function will be called by `bundleRenderer`.
// This is where we perform data-prefetching to determine the
// state of our application before actually rendering it.
// Since data fetching is async, this function is expected to
// return a Promise that resolves to the app instance.
export default context => { export default context => {
// set router's location // set router's location
router.push(context.url) router.push(context.url)
// call prefetch hooks on components matched by the route
const s = isDev && Date.now() const s = isDev && Date.now()
// Call preFetch hooks on components matched by the route.
// A preFetch hook dispatches a store action and returns a Promise,
// which is resolved when the action is complete and store state has been
// updated.
return Promise.all(router.getMatchedComponents().map(component => { return Promise.all(router.getMatchedComponents().map(component => {
if (component.preFetch) { if (component.preFetch) {
return component.preFetch(store) return component.preFetch(store)
} }
})).then(() => { })).then(() => {
isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`) isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`)
// set initial store on context // After all preFetch hooks are resolved, our store is now
// the request handler will inline the state in the HTML response. // filled with the needed state to render the app.
// Expose the state on the render context, and let the request handler
// inline the state in the HTML response. This allows the client-side
// store to pick-up the server-side state without having to duplicate
// the initial data fetching on the client.
context.initialState = store.state context.initialState = store.state
return app return app
}) })
......
import ItemList from '../components/ItemList.vue' import ItemList from '../components/ItemList.vue'
// factory function for 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.
export function createListView (type) { export function createListView (type) {
return { return {
name: `${type}-stories-view`, name: `${type}-stories-view`,
......
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