if (Component.asyncData) {
return Component.asyncData({
store,
route: router.currentRoute,
});
}
})).then(() => {
// 在所有预取钩子(preFetch hook) resolve 后,
// 我们的 store 现在已经填充入渲染应用程序所需的状态。
// 当我们将状态附加到上下文,并且 `template` 选项用于 renderer 时,
// 状态将自动序列化为 `window.__INITIAL_STATE__`,并注入 HTML。
context.state = store.state;
resolve(app);
}).catch(reject);
}, reject);
});
}
客户端托管全局状态
当服务端使用模板进行渲染时,
context.state将作为
window.__INITIAL_STATE__状态,自动嵌入到最终的
HTML 中。而在客户端,在挂载到应用程序之前,
store就应该获取到状态,最终我们的
entry-client.js被改造为如下所示:
import createApp from './app';const { app, router, store } = createApp();
// 客户端把初始化的store替换为window.__INITIAL_STATE__
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__);
}
if (router) {
router.onReady(() => {
app.$mount('#app')
});
} else {
app.$mount('#app');
}
常见问题的解决方案
至此,基本的代码改造也已经完成了,下面说的是一些常见问题的解决方案:
在服务端没有
window、
location对象:对于旧项目迁移到
SSR肯定会经历的问题,一般为在项目入口处或是
created、
beforeCreate生命周期使用了
DOM操作,或是获取了
location对象,通用的解决方案一般为判断执行环境,通过
typeof window是否为
'undefined',如果遇到必须使用
location对象的地方用于获取
url中的相关参数,在
ctx对象中也可以找到对应参数。
vue-router报错
Uncaught TypeError: _Vue.extend is not _Vue function,没有找到
_Vue










