// 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. exportdefault (context) => { returnnewPromise((resolve, reject) => { const s = isDev && Date.now(); const { app, router, store } = createApp();
if (fullPath !== url) { returnreject({ url: fullPath }); }
//设置路由位置 // set router's location router.push(url);
//等待路由可能的异步钩子 // wait until router has resolved possible async hooks router.onReady(() => { const matchedComponents = router.getMatchedComponents(); // no matched routes if (!matchedComponents.length) { returnreject({ code: 404 }); } //路由上匹配的组件唤醒fetchData钩子 //一个预置钩子匹配一个状态返回promise //当解析完成且状态更新 // Call fetchData 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. // 使用Promise.all执行匹配到的Component的asyncData方法,即预取数据 Promise.all( matchedComponents.map( ({ asyncData }) => asyncData && asyncData({ store, route: router.currentRoute, }) ) ) .then(() => { isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`); //解析了所有prefetch钩子后,渲染app所需要的state充满了store,
// After all preFetch hooks are resolved, our store is now // filled with the state needed 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.
// 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. // They are essentially higher order components wrapping ItemList.vue. exportdefaultfunctioncreateListView(type) { return { name: `${type}-stories-view`, //从store中取值 asyncData({ store }) { return store.dispatch("FETCH_LIST_DATA", { type }); },
asyncData 方法被调用,通过 store.dispatch 分发了一个数据预取的事件,接下来我们可以看到通过 FireBase 的 API 获取到 Top 分类的数据,然后又做了一系列的内部事件分发,保存数据状态到 Vuex store,获取 Top 页面的 List 子项数据,最后处理并保存数据到 store.